mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-05-29 21:10:24 +02:00
More audio focus changes.
This commit is contained in:
parent
3cf4a52a69
commit
249e77a5d3
@ -55,11 +55,15 @@ class MediaPlaybackService : Service() {
|
|||||||
private var _notificationChannel: NotificationChannel? = null;
|
private var _notificationChannel: NotificationChannel? = null;
|
||||||
private var _mediaSession: MediaSessionCompat? = null;
|
private var _mediaSession: MediaSessionCompat? = null;
|
||||||
private var _hasFocus: Boolean = false;
|
private var _hasFocus: Boolean = false;
|
||||||
|
private var _isTransientLoss: Boolean = false;
|
||||||
private var _focusRequest: AudioFocusRequest? = null;
|
private var _focusRequest: AudioFocusRequest? = null;
|
||||||
private var _audioFocusLossTime_ms: Long? = null
|
private var _audioFocusLossTime_ms: Long? = null
|
||||||
private var _playbackState = PlaybackStateCompat.STATE_NONE;
|
private var _playbackState = PlaybackStateCompat.STATE_NONE;
|
||||||
private val _handler = Handler(Looper.getMainLooper())
|
private var _lastAudioFocusAttempt_ms: Long? = null
|
||||||
private val _audioFocusRunnable = Runnable { setAudioFocus(false) }
|
private val isPlaying get() = _playbackState != PlaybackStateCompat.STATE_PAUSED &&
|
||||||
|
_playbackState != PlaybackStateCompat.STATE_STOPPED &&
|
||||||
|
_playbackState != PlaybackStateCompat.STATE_NONE &&
|
||||||
|
_playbackState != PlaybackStateCompat.STATE_ERROR
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
Logger.v(TAG, "onStartCommand");
|
Logger.v(TAG, "onStartCommand");
|
||||||
@ -161,14 +165,7 @@ class MediaPlaybackService : Service() {
|
|||||||
Logger.v(TAG, "closeMediaSession");
|
Logger.v(TAG, "closeMediaSession");
|
||||||
stopForeground(STOP_FOREGROUND_REMOVE);
|
stopForeground(STOP_FOREGROUND_REMOVE);
|
||||||
|
|
||||||
val focusRequest = _focusRequest;
|
abandonAudioFocus()
|
||||||
if (focusRequest != null) {
|
|
||||||
Logger.i(TAG, "Audio focus abandoned")
|
|
||||||
_handler.removeCallbacks(_audioFocusRunnable)
|
|
||||||
_audioManager?.abandonAudioFocusRequest(focusRequest);
|
|
||||||
_focusRequest = null;
|
|
||||||
}
|
|
||||||
_hasFocus = false;
|
|
||||||
|
|
||||||
val notifManager = _notificationManager;
|
val notifManager = _notificationManager;
|
||||||
Logger.i(TAG, "Cancelling playback notification (notifManager: ${notifManager != null})");
|
Logger.i(TAG, "Cancelling playback notification (notifManager: ${notifManager != null})");
|
||||||
@ -339,27 +336,34 @@ class MediaPlaybackService : Service() {
|
|||||||
.setState(state, pos, 1f, SystemClock.elapsedRealtime())
|
.setState(state, pos, 1f, SystemClock.elapsedRealtime())
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
if(_focusRequest == null)
|
|
||||||
setAudioFocus();
|
|
||||||
|
|
||||||
_playbackState = state;
|
_playbackState = state;
|
||||||
|
try {
|
||||||
|
setAudioFocus()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Logger.e(TAG, "Failed to set audio focus", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: (TBD) This code probably more fitting inside FutoVideoPlayer, as this service is generally only used for global events
|
//TODO: (TBD) This code probably more fitting inside FutoVideoPlayer, as this service is generally only used for global events
|
||||||
private fun setAudioFocus(createFocusRequest: Boolean = true) {
|
private fun setAudioFocus() {
|
||||||
_handler.removeCallbacks(_audioFocusRunnable)
|
if (!isPlaying) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (_hasFocus) {
|
if (_hasFocus || _isTransientLoss) {
|
||||||
Log.i(TAG, "Skipped trying to get audio focus because audio focus is already obtained.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_focusRequest == null) {
|
val now = System.currentTimeMillis()
|
||||||
if (!createFocusRequest) {
|
val lastAudioFocusAttempt_ms = _lastAudioFocusAttempt_ms
|
||||||
Log.i(TAG, "Skipped trying to get audio focus because createFocusRequest = false and no focus request exists.");
|
if (lastAudioFocusAttempt_ms == null || now - lastAudioFocusAttempt_ms > 1000) {
|
||||||
return;
|
_lastAudioFocusAttempt_ms = now
|
||||||
}
|
} else {
|
||||||
|
Log.v(TAG, "Skipped trying to get audio focus because gaining audio focus was recently attempted.");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_focusRequest == null) {
|
||||||
val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
|
val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
|
||||||
.setAcceptsDelayedFocusGain(true)
|
.setAcceptsDelayedFocusGain(true)
|
||||||
.setOnAudioFocusChangeListener(_audioFocusChangeListener)
|
.setOnAudioFocusChangeListener(_audioFocusChangeListener)
|
||||||
@ -374,27 +378,39 @@ class MediaPlaybackService : Service() {
|
|||||||
val result = _audioManager?.requestAudioFocus(_focusRequest!!)
|
val result = _audioManager?.requestAudioFocus(_focusRequest!!)
|
||||||
Log.i(TAG, "Audio focus request result $result");
|
Log.i(TAG, "Audio focus request result $result");
|
||||||
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||||
_hasFocus = true;
|
_hasFocus = true
|
||||||
Log.i(TAG, "Audio focus received");
|
Log.i(TAG, "Audio focus received");
|
||||||
} else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
|
} else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
|
||||||
_hasFocus = false
|
_hasFocus = false
|
||||||
|
_isTransientLoss = false
|
||||||
Log.i(TAG, "Audio focus delayed, waiting for focus")
|
Log.i(TAG, "Audio focus delayed, waiting for focus")
|
||||||
} else {
|
} else {
|
||||||
_hasFocus = false
|
_hasFocus = false
|
||||||
Log.i(TAG, "Audio focus not granted, retrying in 1 second")
|
_isTransientLoss = false
|
||||||
_handler.postDelayed(_audioFocusRunnable, 1000)
|
Log.i(TAG, "Audio focus not granted, retrying later")
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(TAG, "Audio focus requested.");
|
Log.i(TAG, "Audio focus requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun abandonAudioFocus() {
|
||||||
|
val focusRequest = _focusRequest;
|
||||||
|
if (focusRequest != null) {
|
||||||
|
Logger.i(TAG, "Audio focus abandoned")
|
||||||
|
_audioManager?.abandonAudioFocusRequest(focusRequest);
|
||||||
|
_focusRequest = null;
|
||||||
|
}
|
||||||
|
_hasFocus = false;
|
||||||
|
_isTransientLoss = false;
|
||||||
|
}
|
||||||
|
|
||||||
private val _audioFocusChangeListener =
|
private val _audioFocusChangeListener =
|
||||||
OnAudioFocusChangeListener { focusChange ->
|
OnAudioFocusChangeListener { focusChange ->
|
||||||
try {
|
try {
|
||||||
when (focusChange) {
|
when (focusChange) {
|
||||||
AudioManager.AUDIOFOCUS_GAIN -> {
|
AudioManager.AUDIOFOCUS_GAIN -> {
|
||||||
_handler.removeCallbacks(_audioFocusRunnable)
|
|
||||||
_hasFocus = true;
|
_hasFocus = true;
|
||||||
|
_isTransientLoss = false;
|
||||||
Log.i(TAG, "Audio focus gained (restartPlaybackAfterLoss = ${Settings.instance.playback.restartPlaybackAfterLoss}, _audioFocusLossTime_ms = $_audioFocusLossTime_ms)");
|
Log.i(TAG, "Audio focus gained (restartPlaybackAfterLoss = ${Settings.instance.playback.restartPlaybackAfterLoss}, _audioFocusLossTime_ms = $_audioFocusLossTime_ms)");
|
||||||
|
|
||||||
if (Settings.instance.playback.restartPlaybackAfterLoss == 1) {
|
if (Settings.instance.playback.restartPlaybackAfterLoss == 1) {
|
||||||
@ -412,31 +428,27 @@ class MediaPlaybackService : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
|
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
|
||||||
if (_playbackState != PlaybackStateCompat.STATE_PAUSED &&
|
if (isPlaying) {
|
||||||
_playbackState != PlaybackStateCompat.STATE_STOPPED &&
|
|
||||||
_playbackState != PlaybackStateCompat.STATE_NONE &&
|
|
||||||
_playbackState != PlaybackStateCompat.STATE_ERROR) {
|
|
||||||
_audioFocusLossTime_ms = System.currentTimeMillis()
|
_audioFocusLossTime_ms = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasFocus = false;
|
_hasFocus = false;
|
||||||
|
_isTransientLoss = true;
|
||||||
MediaControlReceiver.onPauseReceived.emit();
|
MediaControlReceiver.onPauseReceived.emit();
|
||||||
Log.i(TAG, "Audio focus transient loss (_audioFocusLossTime_ms = ${_audioFocusLossTime_ms})");
|
Log.i(TAG, "Audio focus transient loss (_audioFocusLossTime_ms = ${_audioFocusLossTime_ms})");
|
||||||
}
|
}
|
||||||
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
|
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
|
||||||
Log.i(TAG, "Audio focus transient loss, can duck");
|
Log.i(TAG, "Audio focus transient loss, can duck");
|
||||||
_hasFocus = true;
|
_hasFocus = true;
|
||||||
|
_isTransientLoss = true;
|
||||||
}
|
}
|
||||||
AudioManager.AUDIOFOCUS_LOSS -> {
|
AudioManager.AUDIOFOCUS_LOSS -> {
|
||||||
if (_playbackState != PlaybackStateCompat.STATE_PAUSED &&
|
if (isPlaying) {
|
||||||
_playbackState != PlaybackStateCompat.STATE_STOPPED &&
|
|
||||||
_playbackState != PlaybackStateCompat.STATE_NONE &&
|
|
||||||
_playbackState != PlaybackStateCompat.STATE_ERROR) {
|
|
||||||
_audioFocusLossTime_ms = System.currentTimeMillis()
|
_audioFocusLossTime_ms = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasFocus = false;
|
|
||||||
MediaControlReceiver.onPauseReceived.emit();
|
MediaControlReceiver.onPauseReceived.emit();
|
||||||
|
abandonAudioFocus();
|
||||||
Log.i(TAG, "Audio focus lost");
|
Log.i(TAG, "Audio focus lost");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user