summaryrefslogtreecommitdiff
path: root/core/src/main/java/de
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/de')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java47
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java28
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java58
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java4
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java90
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java11
8 files changed, 182 insertions, 63 deletions
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 d6ac8496b..6c0aff15e 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
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
-import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -95,9 +94,12 @@ public class UserPreferences {
public static final String PREF_QUEUE_LOCKED = "prefQueueLocked";
public static final String IMAGE_CACHE_DEFAULT_VALUE = "100";
public static final int IMAGE_CACHE_SIZE_MINIMUM = 20;
+ public static final String PREF_LEFT_VOLUME = "prefLeftVolume";
+ public static final String PREF_RIGHT_VOLUME = "prefRightVolume";
// Experimental
public static final String PREF_SONIC = "prefSonic";
+ public static final String PREF_STEREO_TO_MONO = "PrefStereoToMono";
public static final String PREF_NORMALIZER = "prefNormalizer";
public static final int EPISODE_CLEANUP_QUEUE = -1;
public static final int EPISODE_CLEANUP_NULL = -2;
@@ -249,17 +251,37 @@ public class UserPreferences {
}
public static String getPlaybackSpeed() {
- return prefs.getString(PREF_PLAYBACK_SPEED, "1.0");
+ return prefs.getString(PREF_PLAYBACK_SPEED, "1.00");
}
public static String[] getPlaybackSpeedArray() {
return readPlaybackSpeedArray(prefs.getString(PREF_PLAYBACK_SPEED_ARRAY, null));
}
+ public static float getLeftVolume() {
+ int volume = prefs.getInt(PREF_LEFT_VOLUME, 100);
+ if(volume == 100) {
+ return 1.0f;
+ } else {
+ return (float) (1 - (Math.log(100 - volume) / Math.log(100)));
+ }
+ }
+
+ public static float getRightVolume() {
+ int volume = prefs.getInt(PREF_RIGHT_VOLUME, 100);
+ if(volume == 100) {
+ return 1.0f;
+ } else {
+ return (float) (1 - (Math.log(100 - volume) / Math.log(100)));
+ }
+ }
+
public static boolean shouldPauseForFocusLoss() {
return prefs.getBoolean(PREF_PAUSE_PLAYBACK_FOR_FOCUS_LOSS, false);
}
+
+
public static long getUpdateInterval() {
String updateInterval = prefs.getString(PREF_UPDATE_INTERVAL, "0");
if(false == updateInterval.contains(":")) {
@@ -385,6 +407,15 @@ public class UserPreferences {
.apply();
}
+ public static void setVolume(int leftVolume, int rightVolume) {
+ assert(0 <= leftVolume && leftVolume <= 100);
+ assert(0 <= rightVolume && rightVolume <= 100);
+ prefs.edit()
+ .putInt(PREF_LEFT_VOLUME, leftVolume)
+ .putInt(PREF_RIGHT_VOLUME, rightVolume)
+ .apply();
+ }
+
public static void setAutodownloadSelectedNetworks(String[] value) {
prefs.edit()
.putString(PREF_AUTODL_SELECTED_NETWORKS, TextUtils.join(",", value))
@@ -472,7 +503,7 @@ public class UserPreferences {
// If this preference hasn't been set yet, return the default options
if (valueFromPrefs == null) {
String[] allSpeeds = context.getResources().getStringArray(R.array.playback_speed_values);
- List<String> speedList = new LinkedList<String>();
+ List<String> speedList = new ArrayList<>();
for (String speedStr : allSpeeds) {
float speed = Float.parseFloat(speedStr);
if (speed < 2.0001 && speed * 10 % 1 == 0) {
@@ -505,6 +536,16 @@ public class UserPreferences {
.apply();
}
+ public static boolean stereoToMono() {
+ return prefs.getBoolean(PREF_STEREO_TO_MONO, false);
+ }
+
+ public static void stereoToMono(boolean enable) {
+ prefs.edit()
+ .putBoolean(PREF_STEREO_TO_MONO, enable)
+ .apply();
+ }
+
public static EpisodeCleanupAlgorithm getEpisodeCleanupAlgorithm() {
int cleanupValue = Integer.valueOf(prefs.getString(PREF_EPISODE_CLEANUP, "-1"));
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 129055f92..2be075a92 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
@@ -398,19 +398,25 @@ public class PlaybackService extends Service {
@Override
public void onSleepTimerAlmostExpired() {
- mediaPlayer.setVolume(0.1f);
+ float leftVolume = 0.1f * UserPreferences.getLeftVolume();
+ float rightVolume = 0.1f * UserPreferences.getRightVolume();
+ mediaPlayer.setVolume(leftVolume, rightVolume);
}
@Override
public void onSleepTimerExpired() {
mediaPlayer.pause(true, true);
- mediaPlayer.setVolume(1.0f);
+ float leftVolume = UserPreferences.getLeftVolume();
+ float rightVolume = UserPreferences.getRightVolume();
+ mediaPlayer.setVolume(leftVolume, rightVolume);
sendNotificationBroadcast(NOTIFICATION_TYPE_SLEEPTIMER_UPDATE, 0);
}
@Override
public void onSleepTimerReset() {
- mediaPlayer.setVolume(1.0f);
+ float leftVolume = UserPreferences.getLeftVolume();
+ float rightVolume = UserPreferences.getRightVolume();
+ mediaPlayer.setVolume(leftVolume, rightVolume);
}
@Override
@@ -1165,18 +1171,30 @@ public class PlaybackService extends Service {
public Playable getPlayable() { return mediaPlayer.getPlayable(); }
+ public boolean canSetSpeed() {
+ return mediaPlayer.canSetSpeed();
+ }
+
public void setSpeed(float speed) {
mediaPlayer.setSpeed(speed);
}
- public boolean canSetSpeed() {
- return mediaPlayer.canSetSpeed();
+ public void setVolume(float leftVolume, float rightVolume) {
+ mediaPlayer.setVolume(leftVolume, rightVolume);
}
public float getCurrentPlaybackSpeed() {
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/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
index e26ee32cb..aa73b17a7 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/PlaybackServiceMediaPlayer.java
@@ -24,6 +24,7 @@ import android.view.SurfaceHolder;
import android.view.WindowManager;
import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.target.Target;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
@@ -293,6 +294,7 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, p.getDuration());
builder.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, p.getEpisodeTitle());
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, p.getFeedTitle());
+
if (p.getImageUri() != null && UserPreferences.setLockscreenBackground()) {
builder.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, p.getImageUri().toString());
try {
@@ -322,13 +324,10 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
* This method is executed on an internal executor service.
*/
public void resume() {
- executor.submit(new Runnable() {
- @Override
- public void run() {
- playerLock.lock();
- resumeSync();
- playerLock.unlock();
- }
+ executor.submit(() -> {
+ playerLock.lock();
+ resumeSync();
+ playerLock.unlock();
});
}
@@ -339,7 +338,15 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
AudioManager.AUDIOFOCUS_GAIN);
if (focusGained == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
acquireWifiLockIfNecessary();
- setSpeed(Float.parseFloat(UserPreferences.getPlaybackSpeed()));
+ float speed = 1.0f;
+ try {
+ speed = Float.parseFloat(UserPreferences.getPlaybackSpeed());
+ } catch(NumberFormatException e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ UserPreferences.setPlaybackSpeed(String.valueOf(speed));
+ }
+ setSpeed(speed);
+ setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) {
int newPosition = RewindAfterPauseUtils.calculatePositionWithRewind(
@@ -690,24 +697,39 @@ public class PlaybackServiceMediaPlayer implements SharedPreferences.OnSharedPre
* Sets the playback speed.
* This method is executed on an internal executor service.
*/
- public void setVolume(final float volume) {
- executor.submit(new Runnable() {
- @Override
- public void run() {
- setVolumeSync(volume);
- }
- });
+ public void setVolume(final float volumeLeft, float volumeRight) {
+ executor.submit(() -> setVolumeSync(volumeLeft, volumeRight));
}
/**
* Sets the playback speed.
* This method is executed on the caller's thread.
*/
- private void setVolumeSync(float volume) {
+ private void setVolumeSync(float volumeLeft, float volumeRight) {
+ playerLock.lock();
+ if (media != null && media.getMediaType() == MediaType.AUDIO) {
+ 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
+ */
+ public boolean canDownmix() {
+ boolean retVal = false;
+ if (mediaPlayer != null && media != null && media.getMediaType() == MediaType.AUDIO) {
+ retVal = mediaPlayer.canDownmix();
+ }
+ return retVal;
+ }
+
+ public void setDownmix(boolean enable) {
playerLock.lock();
if (media != null && media.getMediaType() == MediaType.AUDIO) {
- mediaPlayer.setVolume(volume, volume);
- Log.d(TAG, "Media player volume was set to " + volume);
+ mediaPlayer.setDownmix(enable);
+ Log.d(TAG, "Media player downmix was set to " + enable);
}
playerLock.unlock();
}
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 b6beb5bf1..f0850e6df 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
@@ -37,4 +37,9 @@ public class AudioPlayer extends MediaPlayer implements IPlayer {
protected boolean useSonic() {
return UserPreferences.useSonic();
}
+
+ @Override
+ protected boolean downmix() {
+ return UserPreferences.stereoToMono();
+ }
}
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 147c7848d..d67153a4e 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
@@ -10,6 +10,8 @@ public interface IPlayer {
boolean canSetSpeed();
+ boolean canDownmix();
+
float getCurrentPitchStepsAdjustment();
int getCurrentPosition();
@@ -57,6 +59,8 @@ public interface IPlayer {
void setPlaybackSpeed(float f);
+ void setDownmix(boolean enable);
+
void setVolume(float left, float right);
void start();
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 a519fb555..1952c068f 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
@@ -27,7 +27,6 @@ import android.widget.TextView;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -48,6 +47,7 @@ import de.danoeh.antennapod.core.util.playback.Playable.PlayableUtils;
* control playback instead of communicating with the PlaybackService directly.
*/
public abstract class PlaybackController {
+
private static final String TAG = "PlaybackController";
public static final int INVALID_TIME = -1;
@@ -78,23 +78,18 @@ public abstract class PlaybackController {
this.activity = activity;
this.reinitOnPause = reinitOnPause;
schedExecutor = new ScheduledThreadPoolExecutor(SCHED_EX_POOLSIZE,
- new ThreadFactory() {
-
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setPriority(Thread.MIN_PRIORITY);
- return t;
- }
- }, new RejectedExecutionHandler() {
-
- @Override
- public void rejectedExecution(Runnable r,
- ThreadPoolExecutor executor) {
- Log.w(TAG,
+ r -> {
+ Thread t = new Thread(r);
+ t.setPriority(Thread.MIN_PRIORITY);
+ return t;
+ }, new RejectedExecutionHandler() {
+ @Override
+ public void rejectedExecution(Runnable r,
+ ThreadPoolExecutor executor) {
+ Log.w(TAG,
"Rejected execution of runnable in schedExecutor");
+ }
}
- }
);
}
@@ -104,10 +99,10 @@ public abstract class PlaybackController {
*/
public void init() {
activity.registerReceiver(statusUpdate, new IntentFilter(
- PlaybackService.ACTION_PLAYER_STATUS_CHANGED));
+ PlaybackService.ACTION_PLAYER_STATUS_CHANGED));
activity.registerReceiver(notificationReceiver, new IntentFilter(
- PlaybackService.ACTION_PLAYER_NOTIFICATION));
+ PlaybackService.ACTION_PLAYER_NOTIFICATION));
activity.registerReceiver(shutdownReceiver, new IntentFilter(
PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
@@ -239,7 +234,7 @@ public abstract class PlaybackController {
return null;
}
- public abstract void setupGUI();
+
private void setupPositionObserver() {
if ((positionObserverFuture != null && positionObserverFuture
@@ -263,8 +258,6 @@ public abstract class PlaybackController {
}
}
- public abstract void onPositionObserverUpdate();
-
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
playbackService = ((PlaybackService.LocalBinder) service)
@@ -367,26 +360,31 @@ public abstract class PlaybackController {
}
};
- public abstract void onPlaybackSpeedChange();
+ public void setupGUI() {};
+
+ public void onPositionObserverUpdate() {};
+
- public abstract void onShutdownNotification();
+ public void onPlaybackSpeedChange() {};
+
+ public void onShutdownNotification() {};
/**
* Called when the currently displayed information should be refreshed.
*/
- public abstract void onReloadNotification(int code);
+ public void onReloadNotification(int code) {};
- public abstract void onBufferStart();
+ public void onBufferStart() {};
- public abstract void onBufferEnd();
+ public void onBufferEnd() {};
- public abstract void onBufferUpdate(float progress);
+ public void onBufferUpdate(float progress) {};
- public abstract void onSleepTimerUpdate();
+ public void onSleepTimerUpdate() {};
- public abstract void handleError(int code);
+ public void handleError(int code) {};
- public abstract void onPlaybackEnd();
+ public void onPlaybackEnd() {};
public void repeatHandleStatus() {
if (status != null && playbackService != null) {
@@ -484,15 +482,19 @@ public abstract class PlaybackController {
}
}
- public abstract ImageButton getPlayButton();
+ public ImageButton getPlayButton() {
+ return null;
+ };
- public abstract void postStatusMsg(int msg);
+ public void postStatusMsg(int msg) {};
- public abstract void clearStatusMsg();
+ public void clearStatusMsg() {};
- public abstract boolean loadMediaInfo();
+ public boolean loadMediaInfo() {
+ return false;
+ };
- public abstract void onAwaitingVideoSurface();
+ public void onAwaitingVideoSurface() {};
/**
* Called when connection to playback service has been established or
@@ -526,7 +528,7 @@ public abstract class PlaybackController {
}
}
- public abstract void onServiceQueried();
+ public void onServiceQueried() {};
/**
* Should be used by classes which implement the OnSeekBarChanged interface.
@@ -691,6 +693,12 @@ public abstract class PlaybackController {
}
}
+ public void setVolume(float leftVolume, float rightVolume) {
+ if (playbackService != null) {
+ playbackService.setVolume(leftVolume, rightVolume);
+ }
+ }
+
public float getCurrentPlaybackSpeedMultiplier() {
if (canSetPlaybackSpeed()) {
return playbackService.getCurrentPlaybackSpeed();
@@ -699,6 +707,16 @@ public abstract class PlaybackController {
}
}
+ public boolean canDownmix() {
+ return playbackService != null && playbackService.canDownmix();
+ }
+
+ public void setDownmix(boolean enable) {
+ if(playbackService != null) {
+ playbackService.setDownmix(enable);
+ }
+ }
+
public boolean isPlayingVideo() {
if (playbackService != null) {
return PlaybackService.getCurrentMediaType() == MediaType.VIDEO;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
index 00f2e6f57..2eee1ac87 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
@@ -88,7 +88,7 @@ public class Timeline {
}
// replace ASCII line breaks with HTML ones if shownotes don't contain HTML line breaks already
- if(!LINE_BREAK_REGEX.matcher(shownotes).find()) {
+ if(!LINE_BREAK_REGEX.matcher(shownotes).find() && !shownotes.contains("<p>")) {
shownotes = shownotes.replace("\n", "<br />");
}
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 dc5270d8f..368379509 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
@@ -17,6 +17,11 @@ public class VideoPlayer extends MediaPlayer implements IPlayer {
}
@Override
+ public boolean canDownmix() {
+ return false;
+ }
+
+ @Override
public float getCurrentPitchStepsAdjustment() {
return 1;
}
@@ -60,6 +65,12 @@ public class VideoPlayer extends MediaPlayer implements IPlayer {
throw new UnsupportedOperationException("Setting playback speed unsupported in video player");
}
+ @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);