mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-29 21:32:41 +00:00
Added support for audio ducking (not just loss of focus).
This commit is contained in:
parent
59b96d2891
commit
20a19218fb
@ -9,6 +9,8 @@ import io.casey.musikcube.remote.util.Preconditions;
|
||||
|
||||
public abstract class PlayerWrapper {
|
||||
private static final String TAG = "MediaPlayerWrapper";
|
||||
private static final float DUCK_COEF = 0.2f; /* volume = 20% when ducked */
|
||||
private static final float DUCK_NONE = -1.0f;
|
||||
|
||||
public enum State {
|
||||
Stopped,
|
||||
@ -29,19 +31,52 @@ public abstract class PlayerWrapper {
|
||||
private static Set<PlayerWrapper> activePlayers = new HashSet<>();
|
||||
private static float globalVolume = 1.0f;
|
||||
private static boolean globalMuted = false;
|
||||
private static float preDuckGlobalVolume = DUCK_NONE;
|
||||
|
||||
public static void setGlobalVolume(final float volume) {
|
||||
public static void duck() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
||||
globalVolume = volume;
|
||||
for (final PlayerWrapper w : activePlayers) {
|
||||
w.updateVolume();
|
||||
if (preDuckGlobalVolume == DUCK_NONE) {
|
||||
final float lastVolume = globalVolume;
|
||||
setGlobalVolume(globalVolume * DUCK_COEF);
|
||||
preDuckGlobalVolume = lastVolume;
|
||||
}
|
||||
}
|
||||
|
||||
public static void unduck() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
||||
if (preDuckGlobalVolume != DUCK_NONE) {
|
||||
final float temp = preDuckGlobalVolume;
|
||||
preDuckGlobalVolume = DUCK_NONE;
|
||||
setGlobalVolume(temp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setGlobalVolume(float volume) {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
||||
if (preDuckGlobalVolume != DUCK_NONE) {
|
||||
preDuckGlobalVolume = volume;
|
||||
volume = volume * DUCK_COEF;
|
||||
}
|
||||
|
||||
if (volume != globalVolume) {
|
||||
globalVolume = volume;
|
||||
for (final PlayerWrapper w : activePlayers) {
|
||||
w.updateVolume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float getGlobalVolume() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
return globalMuted ? 0 : globalVolume;
|
||||
|
||||
if (globalMuted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (preDuckGlobalVolume == DUCK_NONE) ? globalVolume : preDuckGlobalVolume;
|
||||
}
|
||||
|
||||
public static void setGlobalMute(final boolean muted) {
|
||||
|
@ -858,23 +858,23 @@ public class StreamingPlaybackService implements PlaybackService {
|
||||
|
||||
private Runnable pauseServiceShutdownRunnable = () -> SystemService.shutdown();
|
||||
|
||||
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener
|
||||
= new AudioManager.OnAudioFocusChangeListener() {
|
||||
@Override
|
||||
public void onAudioFocusChange(int flag) {
|
||||
switch (flag) {
|
||||
case AudioManager.AUDIOFOCUS_GAIN:
|
||||
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
|
||||
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
|
||||
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
|
||||
break;
|
||||
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = (flag) -> {
|
||||
switch (flag) {
|
||||
case AudioManager.AUDIOFOCUS_GAIN:
|
||||
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
|
||||
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
|
||||
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
|
||||
PlayerWrapper.unduck();
|
||||
break;
|
||||
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
|
||||
killAudioFocus();
|
||||
break;
|
||||
}
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
killAudioFocus();
|
||||
break;
|
||||
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
|
||||
PlayerWrapper.duck();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -77,10 +77,6 @@ public class SystemService extends Service {
|
||||
public static void shutdown() {
|
||||
final Context c = Application.getInstance();
|
||||
c.startService(new Intent(c, SystemService.class).setAction(ACTION_SHUT_DOWN));
|
||||
|
||||
final Exception ex = new Exception();
|
||||
ex.fillInStackTrace();
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -266,8 +262,8 @@ public class SystemService extends Service {
|
||||
}
|
||||
else if (albumArtModel.is(artist, album)) {
|
||||
if (image == null && Strings.notEmpty(albumArtModel.getUrl())) {
|
||||
/* lookup may have failed -- try again. if the fetch is already in
|
||||
progress this will be a no-op */
|
||||
/* lookup may have failed -- try again. if the fetch is already in
|
||||
progress this will be a no-op */
|
||||
albumArtModel.fetch();
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ public interface Prefs {
|
||||
String CERT_VALIDATION_DISABLED = "cert_validation_disabled";
|
||||
String TRANSCODER_BITRATE_INDEX = "transcoder_bitrate_index";
|
||||
String DISK_CACHE_SIZE_INDEX = "disk_cache_size_index";
|
||||
String SYSTEM_SERVICE_FOR_REMOTE = "system_service_for_remote";
|
||||
}
|
||||
|
||||
interface Default {
|
||||
@ -31,5 +32,6 @@ public interface Prefs {
|
||||
boolean CERT_VALIDATION_DISABLED = false;
|
||||
int TRANSCODER_BITRATE_INDEX = 0;
|
||||
int DISK_CACHE_SIZE_INDEX = 0;
|
||||
boolean SYSTEM_SERVICE_FOR_REMOTE = false;
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,7 @@
|
||||
<string name="settings_ssl_dialog_message">the musikcube server doesn\'t support ssl by default. it does, however, work very well with nginx and ssl termination. press \'learn more\' for configuration information.</string>
|
||||
<string name="settings_disable_cert_validation_title">certificate verification</string>
|
||||
<string name="settings_disable_cert_validation_message">there is really no reason to enable this setting. ssl without certificate validation opens you up to man-in-the-middle attacks, and only adds a false sense of security.\n\nare you sure you want to enable this setting?</string>
|
||||
<string name="settings_enable_notification_for_remote_playback">enable lock screen integration for remote playback</string>
|
||||
<string name="unknown_artist">[unknown artist]</string>
|
||||
<string name="unknown_album">[unknown album]</string>
|
||||
<string name="unknown_title">[unknown title]</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user