diff options
Diffstat (limited to 'core/src/main/java/de/danoeh/antennapod')
7 files changed, 276 insertions, 83 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java index 96e3a77be..f7db11af6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java @@ -89,7 +89,7 @@ class UpdateManager { } if(oldVersionCode < 1050004) { if(MediaPlayer.isPrestoLibraryInstalled(context) && Build.VERSION.SDK_INT >= 16) { - UserPreferences.enableSonic(true); + UserPreferences.enableSonic(); } } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index 44b2fa2b2..2bdefcb45 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -97,6 +97,7 @@ public class UserPreferences { public static final String PREF_IMAGE_CACHE_SIZE = "prefImageCacheSize"; // Mediaplayer + public static final String PREF_MEDIA_PLAYER = "prefMediaPlayer"; private static final String PREF_PLAYBACK_SPEED = "prefPlaybackSpeed"; private static final String PREF_FAST_FORWARD_SECS = "prefFastForwardSecs"; private static final String PREF_REWIND_SECS = "prefRewindSecs"; @@ -107,7 +108,6 @@ public class UserPreferences { private static final String PREF_RIGHT_VOLUME = "prefRightVolume"; // Experimental - public static final String PREF_SONIC = "prefSonic"; private static final String PREF_STEREO_TO_MONO = "PrefStereoToMono"; public static final String PREF_NORMALIZER = "prefNormalizer"; public static final String PREF_CAST_ENABLED = "prefCast"; //Used for enabling Chromecast support @@ -636,13 +636,15 @@ public class UserPreferences { } public static boolean useSonic() { - return prefs.getBoolean(PREF_SONIC, false); + return prefs.getString(PREF_MEDIA_PLAYER, "sonic").equals("sonic"); } - public static void enableSonic(boolean enable) { - prefs.edit() - .putBoolean(PREF_SONIC, enable) - .apply(); + public static boolean useExoplayer() { + return prefs.getString(PREF_MEDIA_PLAYER, "sonic").equals("exoplayer"); + } + + public static void enableSonic() { + prefs.edit().putString(PREF_MEDIA_PLAYER, "sonic").apply(); } public static boolean stereoToMono() { 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 new file mode 100644 index 000000000..3df017e58 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java @@ -0,0 +1,245 @@ +package de.danoeh.antennapod.core.service.playback; + +import android.content.Context; +import android.net.Uri; +import android.view.SurfaceHolder; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.DefaultLoadControl; +import com.google.android.exoplayer2.DefaultRenderersFactory; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.PlaybackParameters; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SeekParameters; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.audio.AudioAttributes; +import com.google.android.exoplayer2.source.ExtractorMediaSource; +import com.google.android.exoplayer2.source.MediaSource; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.util.Util; +import de.danoeh.antennapod.core.util.playback.IPlayer; +import org.antennapod.audio.MediaPlayer; + + +public class ExoPlayerWrapper implements IPlayer { + private final Context mContext; + private SimpleExoPlayer mExoPlayer; + private MediaSource mediaSource; + private MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener; + private MediaPlayer.OnCompletionListener audioCompletionListener; + private MediaPlayer.OnErrorListener audioErrorListener; + + ExoPlayerWrapper(Context context) { + mContext = context; + mExoPlayer = createPlayer(); + } + + private SimpleExoPlayer createPlayer() { + SimpleExoPlayer p = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(mContext), + new DefaultTrackSelector(), new DefaultLoadControl()); + p.setSeekParameters(SeekParameters.PREVIOUS_SYNC); + p.addListener(new Player.EventListener() { + @Override + public void onTimelineChanged(Timeline timeline, Object manifest, int reason) { + + } + + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + + } + + @Override + public void onLoadingChanged(boolean isLoading) { + + } + + @Override + public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { + if (playbackState == Player.STATE_ENDED) { + audioCompletionListener.onCompletion(null); + } + } + + @Override + public void onRepeatModeChanged(int repeatMode) { + + } + + @Override + public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { + + } + + @Override + public void onPlayerError(ExoPlaybackException error) { + audioErrorListener.onError(null, 0, 0); + } + + @Override + public void onPositionDiscontinuity(int reason) { + + } + + @Override + public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { + + } + + @Override + public void onSeekProcessed() { + audioSeekCompleteListener.onSeekComplete(null); + } + }); + return p; + } + + @Override + public boolean canSetSpeed() { + return true; + } + + @Override + public boolean canDownmix() { + return false; + } + + @Override + public int getCurrentPosition() { + return (int) mExoPlayer.getCurrentPosition(); + } + + @Override + public float getCurrentSpeedMultiplier() { + return mExoPlayer.getPlaybackParameters().speed; + } + + @Override + public int getDuration() { + if (mExoPlayer.getDuration() == C.TIME_UNSET) { + return PlaybackServiceMediaPlayer.INVALID_TIME; + } + return (int) mExoPlayer.getDuration(); + } + + @Override + public boolean isPlaying() { + return mExoPlayer.getPlayWhenReady(); + } + + @Override + public void pause() { + mExoPlayer.setPlayWhenReady(false); + } + + @Override + public void prepare() throws IllegalStateException { + mExoPlayer.prepare(mediaSource); + } + + @Override + public void release() { + if (mExoPlayer != null) { + mExoPlayer.release(); + } + audioSeekCompleteListener = null; + audioCompletionListener = null; + audioErrorListener = null; + } + + @Override + public void reset() { + mExoPlayer.release(); + mExoPlayer = createPlayer(); + } + + @Override + public void seekTo(int i) throws IllegalStateException { + mExoPlayer.seekTo(i); + } + + @Override + public void setAudioStreamType(int i) { + AudioAttributes a = mExoPlayer.getAudioAttributes(); + AudioAttributes.Builder b = new AudioAttributes.Builder(); + b.setContentType(i); + b.setFlags(a.flags); + b.setUsage(a.usage); + mExoPlayer.setAudioAttributes(b.build()); + } + + @Override + public void setDataSource(String s) throws IllegalArgumentException, IllegalStateException { + DataSource.Factory dataSourceFactory = + new DefaultDataSourceFactory(mContext, Util.getUserAgent(mContext, mContext.getPackageName()), null); + ExtractorMediaSource.Factory f = new ExtractorMediaSource.Factory(dataSourceFactory); + mediaSource = f.createMediaSource(Uri.parse(s)); + } + + @Override + public void setDisplay(SurfaceHolder sh) { + mExoPlayer.setVideoSurfaceHolder(sh); + } + + @Override + public void setPlaybackSpeed(float v) { + PlaybackParameters params = mExoPlayer.getPlaybackParameters(); + mExoPlayer.setPlaybackParameters(new PlaybackParameters(v, params.pitch)); + } + + @Override + public void setDownmix(boolean b) { + + } + + @Override + public void setVolume(float v, float v1) { + mExoPlayer.setVolume(v); + } + + @Override + public void setWakeMode(Context context, int i) { + + } + + @Override + public void start() { + mExoPlayer.setPlayWhenReady(true); + } + + @Override + public void stop() { + mExoPlayer.stop(); + } + + void setOnCompletionListener(MediaPlayer.OnCompletionListener audioCompletionListener) { + this.audioCompletionListener = audioCompletionListener; + } + + void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener) { + this.audioSeekCompleteListener = audioSeekCompleteListener; + } + + void setOnErrorListener(MediaPlayer.OnErrorListener audioErrorListener) { + this.audioErrorListener = audioErrorListener; + } + + int getVideoWidth() { + if (mExoPlayer.getVideoFormat() == null) { + return 0; + } + return mExoPlayer.getVideoFormat().width; + } + + int getVideoHeight() { + if (mExoPlayer.getVideoFormat() == null) { + return 0; + } + return mExoPlayer.getVideoFormat().height; + } +} 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 0e64f484f..66d34fea1 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 @@ -313,7 +313,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { Log.d(TAG, "Resource prepared"); - if (mediaType == MediaType.VIDEO) { + 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()); } @@ -447,7 +450,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { || playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) { retVal = mediaPlayer.getDuration(); - } else if (media != null && media.getDuration() > 0) { + } + if (retVal <= 0 && media != null && media.getDuration() > 0) { retVal = media.getDuration(); } @@ -669,6 +673,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { 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()); @@ -698,15 +706,19 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { if (mediaPlayer != null) { mediaPlayer.release(); } - if(media == null) { + if (media == null) { mediaPlayer = null; return; } - if (media.getMediaType() == MediaType.VIDEO) { + + if (UserPreferences.useExoplayer()) { + mediaPlayer = new ExoPlayerWrapper(context); + } else if (media.getMediaType() == MediaType.VIDEO) { mediaPlayer = new VideoPlayer(); } else { mediaPlayer = new AudioPlayer(context); } + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK); setMediaPlayerListeners(mediaPlayer); @@ -883,6 +895,11 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { ap.setOnBufferingUpdateListener(audioBufferingUpdateListener); ap.setOnInfoListener(audioInfoListener); ap.setOnSpeedAdjustmentAvailableChangedListener(audioSetSpeedAbilityListener); + } else if (mp instanceof ExoPlayerWrapper) { + ExoPlayerWrapper ap = (ExoPlayerWrapper) mp; + ap.setOnCompletionListener(audioCompletionListener); + ap.setOnSeekCompleteListener(audioSeekCompleteListener); + ap.setOnErrorListener(audioErrorListener); } else { Log.w(TAG, "Unknown media player: " + mp); } 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 index 846733882..16d05dbb9 100644 --- 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 @@ -21,18 +21,12 @@ public class AudioPlayer extends MediaPlayer implements IPlayer { private final SharedPreferences.OnSharedPreferenceChangeListener sonicListener = (sharedPreferences, key) -> { - if (key.equals(UserPreferences.PREF_SONIC)) { + if (key.equals(UserPreferences.PREF_MEDIA_PLAYER)) { checkMpi(); } }; @Override - public void setScreenOnWhilePlaying(boolean screenOn) { - Log.e(TAG, "Setting screen on while playing not supported in Audio Player"); - throw new UnsupportedOperationException("Setting screen on while playing not supported in Audio Player"); - } - - @Override public void setDisplay(SurfaceHolder sh) { if (sh != null) { Log.e(TAG, "Setting display not supported in Audio Player"); @@ -40,11 +34,6 @@ public class AudioPlayer extends MediaPlayer implements IPlayer { } } - @Override - public void setVideoScalingMode(int mode) { - throw new UnsupportedOperationException("Setting scaling mode is not supported in Audio Player"); - } - @Override protected boolean useSonic() { return UserPreferences.useSonic(); 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 index aba395ec1..a372f4241 100644 --- 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 @@ -6,13 +6,11 @@ import android.view.SurfaceHolder; import java.io.IOException; public interface IPlayer { - boolean canSetPitch(); boolean canSetSpeed(); boolean canDownmix(); - float getCurrentPitchStepsAdjustment(); int getCurrentPosition(); @@ -20,20 +18,12 @@ public interface IPlayer { int getDuration(); - float getMaxSpeedMultiplier(); - - float getMinSpeedMultiplier(); - - boolean isLooping(); - boolean isPlaying(); void pause(); void prepare() throws IllegalStateException, IOException; - void prepareAsync(); - void release(); void reset(); @@ -42,21 +32,11 @@ public interface IPlayer { void setAudioStreamType(int streamtype); - void setScreenOnWhilePlaying(boolean screenOn); - void setDataSource(String path) throws IllegalStateException, IOException, IllegalArgumentException, SecurityException; void setDisplay(SurfaceHolder sh); - void setEnableSpeedAdjustment(boolean enableSpeedAdjustment); - - void setLooping(boolean looping); - - void setPitchStepsAdjustment(float pitchSteps); - - void setPlaybackPitch(float f); - void setPlaybackSpeed(float f); void setDownmix(boolean enable); @@ -67,7 +47,5 @@ public interface IPlayer { void stop(); - void setVideoScalingMode(int mode); - void setWakeMode(Context context, int mode); } 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 index 368379509..1d04fb878 100644 --- 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 @@ -7,11 +7,6 @@ public class VideoPlayer extends MediaPlayer implements IPlayer { private static final String TAG = "VideoPlayer"; @Override - public boolean canSetPitch() { - return false; - } - - @Override public boolean canSetSpeed() { return false; } @@ -22,44 +17,11 @@ public class VideoPlayer extends MediaPlayer implements IPlayer { } @Override - public float getCurrentPitchStepsAdjustment() { - return 1; - } - - @Override public float getCurrentSpeedMultiplier() { return 1; } @Override - public float getMaxSpeedMultiplier() { - return 1; - } - - @Override - public float getMinSpeedMultiplier() { - return 1; - } - - @Override - public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) throws UnsupportedOperationException { - Log.e(TAG, "Setting enable speed adjustment unsupported in video player"); - throw new UnsupportedOperationException("Setting enable speed adjustment unsupported in video player"); - } - - @Override - public void setPitchStepsAdjustment(float pitchSteps) { - Log.e(TAG, "Setting pitch steps adjustment unsupported in video player"); - throw new UnsupportedOperationException("Setting pitch steps adjustment unsupported in video player"); - } - - @Override - public void setPlaybackPitch(float f) { - Log.e(TAG, "Setting playback pitch unsupported in video player"); - throw new UnsupportedOperationException("Setting playback pitch unsupported in video player"); - } - - @Override public void setPlaybackSpeed(float f) { Log.e(TAG, "Setting playback speed unsupported in video player"); throw new UnsupportedOperationException("Setting playback speed unsupported in video player"); |