diff options
author | Domingos Lopes <domingos86lopes@gmail.com> | 2016-03-19 11:37:37 -0400 |
---|---|---|
committer | Domingos Lopes <domingos86lopes+github@gmail.com> | 2016-04-23 21:39:52 -0400 |
commit | afbae2a7ef8b0466e8e89e82708c2fcb9f77ff35 (patch) | |
tree | 65c87fe15ec3c32e59d1c5ae46c75945088e9628 /core/src/main/java/de/danoeh | |
parent | 8061d94c1b2dcdc99fc0a3c4554a00f01ca4941f (diff) | |
download | AntennaPod-afbae2a7ef8b0466e8e89e82708c2fcb9f77ff35.zip |
Create interface for PlaybackServiceMediaPlayer
Diffstat (limited to 'core/src/main/java/de/danoeh')
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java | 108 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java (renamed from core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java) | 72 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java | 20 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java | 4 |
4 files changed, 154 insertions, 50 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java new file mode 100644 index 000000000..c300d48d1 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/IPlaybackServiceMediaPlayer.java @@ -0,0 +1,108 @@ +package de.danoeh.antennapod.core.service.playback; + +import android.support.annotation.NonNull; +import android.support.v4.media.session.MediaSessionCompat; +import android.util.Pair; +import android.view.KeyEvent; +import android.view.SurfaceHolder; + +import de.danoeh.antennapod.core.feed.Chapter; +import de.danoeh.antennapod.core.feed.MediaType; +import de.danoeh.antennapod.core.util.playback.Playable; + +/** + * Interface that allows for different implementations of the PlaybackServiceMediaPlayer for local + * and remote (cast devices) playback. + */ +public interface IPlaybackServiceMediaPlayer { + void playMediaObject(@NonNull Playable playable, boolean stream, boolean startWhenPrepared, boolean prepareImmediately); + + void resume(); + + void pause(boolean abandonFocus, boolean reinit); + + void prepare(); + + void reinit(); + + void seekTo(int t); + + void seekDelta(int d); + + void seekToChapter(@NonNull Chapter c); + + int getDuration(); + + int getPosition(); + + boolean isStartWhenPrepared(); + + void setStartWhenPrepared(boolean startWhenPrepared); + + boolean canSetSpeed(); + + void setSpeed(float speed); + + float getPlaybackSpeed(); + + void setVolume(float volumeLeft, float volumeRight); + + boolean canDownmix(); + + void setDownmix(boolean enable); + + MediaType getCurrentMediaType(); + + boolean isStreaming(); + + void shutdown(); + + void setVideoSurface(SurfaceHolder surface); + + void resetVideoSurface(); + + Pair<Integer, Integer> getVideoSize(); + + PSMPInfo getPSMPInfo(); + + PlayerStatus getPlayerStatus(); + + Playable getPlayable(); + + void endPlayback(boolean wasSkipped); + + void stop(); + + interface PSMPCallback { + void statusChanged(PSMPInfo newInfo); + + void shouldStop(); + + void playbackSpeedChanged(float s); + + void setSpeedAbilityChanged(); + + void onBufferingUpdate(int percent); + + void updateMediaSessionMetadata(Playable p); + + boolean onMediaPlayerInfo(int code); + + boolean onMediaPlayerError(Object inObj, int what, int extra); + + boolean endPlayback(boolean playNextEpisode, boolean wasSkipped); + } + + /** + * Holds information about a PSMP object. + */ + class PSMPInfo { + public PlayerStatus playerStatus; + public Playable playable; + + public PSMPInfo(PlayerStatus playerStatus, Playable playable) { + this.playerStatus = playerStatus; + this.playable = playable; + } + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java index d8b334295..1293638ed 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java @@ -36,7 +36,7 @@ import de.danoeh.antennapod.core.util.playback.VideoPlayer; /** * Manages the MediaPlayer object of the PlaybackService. */ -public class PlaybackServiceMediaPlayer { +public class LocalPSMP implements IPlaybackServiceMediaPlayer { public static final String TAG = "PlaybackSvcMediaPlayer"; /** @@ -74,8 +74,8 @@ public class PlaybackServiceMediaPlayer { */ private WifiManager.WifiLock wifiLock; - public PlaybackServiceMediaPlayer(@NonNull Context context, - @NonNull PSMPCallback callback) { + public LocalPSMP(@NonNull Context context, + @NonNull PSMPCallback callback) { this.context = context; this.callback = callback; this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); @@ -124,6 +124,7 @@ public class PlaybackServiceMediaPlayer { * for playback immediately (see 'prepareImmediately' parameter for more details) * @param prepareImmediately Set to true if the method should also prepare the episode for playback. */ + @Override public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) { Log.d(TAG, "playMediaObject(...)"); executor.submit(() -> { @@ -194,7 +195,7 @@ public class PlaybackServiceMediaPlayer { this.mediaType = media.getMediaType(); this.videoSize = null; createMediaPlayer(); - PlaybackServiceMediaPlayer.this.startWhenPrepared.set(startWhenPrepared); + LocalPSMP.this.startWhenPrepared.set(startWhenPrepared); setPlayerStatus(PlayerStatus.INITIALIZING, media); try { media.loadMetadata(); @@ -224,6 +225,7 @@ public class PlaybackServiceMediaPlayer { * <p/> * This method is executed on an internal executor service. */ + @Override public void resume() { executor.submit(() -> { playerLock.lock(); @@ -280,6 +282,7 @@ public class PlaybackServiceMediaPlayer { * @param reinit is true if service should reinit after pausing if the media * file is being streamed */ + @Override public void pause(final boolean abandonFocus, final boolean reinit) { executor.submit(() -> { playerLock.lock(); @@ -310,6 +313,7 @@ public class PlaybackServiceMediaPlayer { * <p/> * This method is executed on an internal executor service. */ + @Override public void prepare() { executor.submit(() -> { playerLock.lock(); @@ -370,6 +374,7 @@ public class PlaybackServiceMediaPlayer { * <p/> * This method is executed on an internal executor service. */ + @Override public void reinit() { executor.submit(() -> { playerLock.lock(); @@ -434,6 +439,7 @@ public class PlaybackServiceMediaPlayer { * <p/> * This method is executed on an internal executor service. */ + @Override public void seekTo(final int t) { executor.submit(() -> seekToSync(t)); } @@ -443,6 +449,7 @@ public class PlaybackServiceMediaPlayer { * * @param d offset from current position (positive or negative) */ + @Override public void seekDelta(final int d) { executor.submit(() -> { playerLock.lock(); @@ -460,6 +467,7 @@ public class PlaybackServiceMediaPlayer { /** * Seek to the start of the specified chapter. */ + @Override public void seekToChapter(@NonNull Chapter c) { seekTo((int) c.getStart()); } @@ -467,6 +475,7 @@ public class PlaybackServiceMediaPlayer { /** * Returns the duration of the current media object or INVALID_TIME if the duration could not be retrieved. */ + @Override public int getDuration() { if (!playerLock.tryLock()) { return INVALID_TIME; @@ -488,6 +497,7 @@ public class PlaybackServiceMediaPlayer { /** * Returns the position of the current media object or INVALID_TIME if the position could not be retrieved. */ + @Override public int getPosition() { try { if (!playerLock.tryLock(50, TimeUnit.MILLISECONDS)) { @@ -513,10 +523,12 @@ public class PlaybackServiceMediaPlayer { return retVal; } + @Override public boolean isStartWhenPrepared() { return startWhenPrepared.get(); } + @Override public void setStartWhenPrepared(boolean startWhenPrepared) { this.startWhenPrepared.set(startWhenPrepared); } @@ -524,6 +536,7 @@ public class PlaybackServiceMediaPlayer { /** * Returns true if the playback speed can be adjusted. */ + @Override public boolean canSetSpeed() { boolean retVal = false; if (mediaPlayer != null && media != null && media.getMediaType() == MediaType.AUDIO) { @@ -552,6 +565,7 @@ public class PlaybackServiceMediaPlayer { * Sets the playback speed. * This method is executed on an internal executor service. */ + @Override public void setSpeed(final float speed) { executor.submit(() -> setSpeedSync(speed)); } @@ -559,6 +573,7 @@ public class PlaybackServiceMediaPlayer { /** * Returns the current playback speed. If the playback speed could not be retrieved, 1 is returned. */ + @Override public float getPlaybackSpeed() { if (!playerLock.tryLock()) { return 1; @@ -578,6 +593,7 @@ public class PlaybackServiceMediaPlayer { * Sets the playback volume. * This method is executed on an internal executor service. */ + @Override public void setVolume(final float volumeLeft, float volumeRight) { executor.submit(() -> setVolumeSync(volumeLeft, volumeRight)); } @@ -598,6 +614,7 @@ public class PlaybackServiceMediaPlayer { /** * 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) { @@ -606,6 +623,7 @@ public class PlaybackServiceMediaPlayer { return retVal; } + @Override public void setDownmix(boolean enable) { playerLock.lock(); if (media != null && media.getMediaType() == MediaType.AUDIO) { @@ -615,10 +633,12 @@ public class PlaybackServiceMediaPlayer { playerLock.unlock(); } + @Override public MediaType getCurrentMediaType() { return mediaType; } + @Override public boolean isStreaming() { return stream; } @@ -627,6 +647,7 @@ public class PlaybackServiceMediaPlayer { /** * Releases internally used resources. This method should only be called when the object is not used anymore. */ + @Override public void shutdown() { executor.shutdown(); if (mediaPlayer != null) { @@ -635,6 +656,7 @@ public class PlaybackServiceMediaPlayer { releaseWifiLockIfNecessary(); } + @Override public void setVideoSurface(final SurfaceHolder surface) { executor.submit(() -> { playerLock.lock(); @@ -645,6 +667,7 @@ public class PlaybackServiceMediaPlayer { }); } + @Override public void resetVideoSurface() { executor.submit(() -> { playerLock.lock(); @@ -662,6 +685,7 @@ public class PlaybackServiceMediaPlayer { * return an invalid non-null value if the getVideoWidth() and getVideoHeight() methods of the media player return * invalid values. */ + @Override public Pair<Integer, Integer> getVideoSize() { if (!playerLock.tryLock()) { // use cached value if lock can't be aquired @@ -684,6 +708,7 @@ public class PlaybackServiceMediaPlayer { * * @return The PSMPInfo object. */ + @Override public synchronized PSMPInfo getPSMPInfo() { return new PSMPInfo(playerStatus, media); } @@ -694,6 +719,7 @@ public class PlaybackServiceMediaPlayer { * could result in nonsensical results (like a status of PLAYING, but a null playable) * @return the current player status */ + @Override public PlayerStatus getPlayerStatus() { return playerStatus; } @@ -704,6 +730,7 @@ public class PlaybackServiceMediaPlayer { * could result in nonsensical results (like a status of PLAYING, but a null playable) * @return the current media. May be null */ + @Override public Playable getPlayable() { return media; } @@ -799,6 +826,7 @@ public class PlaybackServiceMediaPlayer { }; + @Override public void endPlayback(final boolean wasSkipped) { executor.submit(() -> { playerLock.lock(); @@ -821,11 +849,12 @@ public class PlaybackServiceMediaPlayer { } /** - * Moves the PlaybackServiceMediaPlayer into STOPPED state. This call is only valid if the player is currently in + * Moves the LocalPSMP into STOPPED state. This call is only valid if the player is currently in * INDETERMINATE state, for example after a call to endPlayback. * This method will only take care of changing the PlayerStatus of this object! Other tasks like * abandoning audio focus have to be done with other methods. */ + @Override public void stop() { executor.submit(() -> { playerLock.lock(); @@ -858,39 +887,6 @@ public class PlaybackServiceMediaPlayer { } } - /** - * Holds information about a PSMP object. - */ - public class PSMPInfo { - public PlayerStatus playerStatus; - public Playable playable; - - public PSMPInfo(PlayerStatus playerStatus, Playable playable) { - this.playerStatus = playerStatus; - this.playable = playable; - } - } - - public interface PSMPCallback { - void statusChanged(PSMPInfo newInfo); - - void shouldStop(); - - void playbackSpeedChanged(float s); - - void setSpeedAbilityChanged(); - - void onBufferingUpdate(int percent); - - void updateMediaSessionMetadata(Playable p); - - boolean onMediaPlayerInfo(int code); - - boolean onMediaPlayerError(Object inObj, int what, int extra); - - boolean endPlayback(boolean playNextEpisode, boolean wasSkipped); - } - private IPlayer setMediaPlayerListeners(IPlayer mp) { if (mp != null && media != null) { if (media.getMediaType() == MediaType.AUDIO) { 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 6ab9859ac..47f7e8dc8 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 @@ -174,7 +174,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar private static final int NOTIFICATION_ID = 1; - private PlaybackServiceMediaPlayer mediaPlayer; + private IPlaybackServiceMediaPlayer mediaPlayer; private PlaybackServiceTaskManager taskManager; /** * Only used for Lollipop notifications. @@ -248,7 +248,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar registerReceiver(pauseResumeCurrentEpisodeReceiver, new IntentFilter( ACTION_RESUME_PLAY_CURRENT_EPISODE)); taskManager = new PlaybackServiceTaskManager(this, taskManagerCallback); - mediaPlayer = new PlaybackServiceMediaPlayer(this, mediaPlayerCallback); + mediaPlayer = new LocalPSMP(this, mediaPlayerCallback); ComponentName eventReceiver = new ComponentName(getApplicationContext(), MediaButtonReceiver.class); @@ -353,7 +353,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar */ private void handleKeycode(int keycode, int source) { Log.d(TAG, "Handling keycode: " + keycode); - final PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo(); + final IPlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo(); final PlayerStatus status = info.playerStatus; switch (keycode) { case KeyEvent.KEYCODE_HEADSETHOOK: @@ -491,9 +491,9 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar } }; - private final PlaybackServiceMediaPlayer.PSMPCallback mediaPlayerCallback = new PlaybackServiceMediaPlayer.PSMPCallback() { + private final IPlaybackServiceMediaPlayer.PSMPCallback mediaPlayerCallback = new IPlaybackServiceMediaPlayer.PSMPCallback() { @Override - public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) { + public void statusChanged(IPlaybackServiceMediaPlayer.PSMPInfo newInfo) { currentMediaType = mediaPlayer.getCurrentMediaType(); updateMediaSession(newInfo.playerStatus); switch (newInfo.playerStatus) { @@ -779,7 +779,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar SharedPreferences.Editor editor = PreferenceManager .getDefaultSharedPreferences(getApplicationContext()).edit(); - PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo(); + IPlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo(); MediaType mediaType = mediaPlayer.getCurrentMediaType(); boolean stream = mediaPlayer.isStreaming(); int playerStatus = getCurrentPlayerStatusAsInt(info.playerStatus); @@ -940,7 +940,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar /** * Prepares notification and starts the service in the foreground. */ - private void setupNotification(final PlaybackServiceMediaPlayer.PSMPInfo info) { + private void setupNotification(final IPlaybackServiceMediaPlayer.PSMPInfo info) { final PendingIntent pIntent = PendingIntent.getActivity(this, 0, PlaybackService.getPlayerActivityIntent(this), PendingIntent.FLAG_UPDATE_CURRENT); @@ -1144,7 +1144,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar return taskManager.getSleepTimerTimeLeft(); } - private void bluetoothNotifyChange(PlaybackServiceMediaPlayer.PSMPInfo info, String whatChanged) { + private void bluetoothNotifyChange(IPlaybackServiceMediaPlayer.PSMPInfo info, String whatChanged) { boolean isPlaying = false; if (info.playerStatus == PlayerStatus.PLAYING) { @@ -1319,7 +1319,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar mediaPlayer.reinit(); } - public PlaybackServiceMediaPlayer.PSMPInfo getPSMPInfo() { + public IPlaybackServiceMediaPlayer.PSMPInfo getPSMPInfo() { return mediaPlayer.getPSMPInfo(); } @@ -1391,7 +1391,7 @@ public class PlaybackService extends Service implements SharedPreferences.OnShar } /** - * @see de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer#seekToChapter(de.danoeh.antennapod.core.feed.Chapter) + * @see LocalPSMP#seekToChapter(de.danoeh.antennapod.core.feed.Chapter) */ public void seekToChapter(Chapter c) { mediaPlayer.seekToChapter(c); 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 1409ffe09..03f0ab497 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 @@ -34,8 +34,8 @@ import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.MediaType; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.playback.LocalPSMP; import de.danoeh.antennapod.core.service.playback.PlaybackService; -import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.util.Converter; @@ -281,7 +281,7 @@ public abstract class PlaybackController { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received statusUpdate Intent."); if (isConnectedToPlaybackService()) { - PlaybackServiceMediaPlayer.PSMPInfo info = playbackService.getPSMPInfo(); + LocalPSMP.PSMPInfo info = playbackService.getPSMPInfo(); status = info.playerStatus; media = info.playable; handleStatus(); |