From ccea00e4056b85d5be0ebfa898a1ac961c2e3c56 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 26 Feb 2023 16:38:31 +0100 Subject: Remove deprecated media players (#6354) --- core/build.gradle | 1 - .../core/service/playback/ExoPlayerWrapper.java | 74 +- .../core/service/playback/LocalPSMP.java | 751 +++++---------------- .../core/service/playback/PlaybackService.java | 8 - .../antennapod/core/util/playback/AudioPlayer.java | 77 --- .../antennapod/core/util/playback/IPlayer.java | 56 -- .../core/util/playback/PlaybackController.java | 12 - .../antennapod/core/util/playback/VideoPlayer.java | 56 -- core/src/main/res/values/arrays.xml | 12 - 9 files changed, 203 insertions(+), 844 deletions(-) delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java (limited to 'core') 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 audioErrorListener; - private MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener; + private Consumer 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 getAudioTracks() { List 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 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 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 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(() -> {}, 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 - *

- * This method is executed on the caller's thread. + * Invalid time values (< 0) will be ignored. + *

+ * 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. - *

- * 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; } @@ -613,25 +429,15 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { this.startWhenPrepared.set(startWhenPrepared); } - /** - * 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 getVideoSize() { - if (!playerLock.tryLock()) { - // use cached value if lock can't be aquired - return videoSize; - } - Pair 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 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 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 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 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 @@ DownloadsSection - - @string/media_player_exoplayer_recommended - @string/media_player_builtin - @string/media_player_sonic - - - - exoplayer - builtin - sonic - - @string/sort_date_new_old -- cgit v1.2.3