Skip to content

Commit

Permalink
Convert AudioReactor to Kotlin.
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Jul 14, 2021
1 parent 9f484cb commit c29b3be
Showing 1 changed file with 90 additions and 126 deletions.
216 changes: 90 additions & 126 deletions app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.kt
Original file line number Diff line number Diff line change
@@ -1,161 +1,125 @@
package org.schabi.newpipe.player.helper;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.audiofx.AudioEffect;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.media.AudioFocusRequestCompat;
import androidx.media.AudioManagerCompat;

import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.analytics.AnalyticsListener;

public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, AnalyticsListener {

private static final String TAG = "AudioFocusReactor";

private static final int DUCK_DURATION = 1500;
private static final float DUCK_AUDIO_TO = .2f;

private static final int FOCUS_GAIN_TYPE = AudioManagerCompat.AUDIOFOCUS_GAIN;
private static final int STREAM_TYPE = AudioManager.STREAM_MUSIC;

private final SimpleExoPlayer player;
private final Context context;
private final AudioManager audioManager;

private final AudioFocusRequestCompat request;

public AudioReactor(@NonNull final Context context,
@NonNull final SimpleExoPlayer player) {
this.player = player;
this.context = context;
this.audioManager = ContextCompat.getSystemService(context, AudioManager.class);
player.addAnalyticsListener(this);

request = new AudioFocusRequestCompat.Builder(FOCUS_GAIN_TYPE)
//.setAcceptsDelayedFocusGain(true)
.setWillPauseWhenDucked(true)
.setOnAudioFocusChangeListener(this)
.build();
package org.schabi.newpipe.player.helper

import android.animation.ValueAnimator
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.media.AudioManager.OnAudioFocusChangeListener
import android.media.audiofx.AudioEffect
import android.util.Log
import androidx.core.animation.addListener
import androidx.core.content.getSystemService
import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.analytics.AnalyticsListener
import com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime

class AudioReactor(
private val context: Context,
private val player: SimpleExoPlayer
) : OnAudioFocusChangeListener, AnalyticsListener {
private val audioManager = context.getSystemService<AudioManager>()!!
private val request = AudioFocusRequestCompat.Builder(FOCUS_GAIN_TYPE)
//.setAcceptsDelayedFocusGain(true)
.setWillPauseWhenDucked(true)
.setOnAudioFocusChangeListener(this)
.build()

init {
player.addAnalyticsListener(this)
}

public void dispose() {
abandonAudioFocus();
player.removeAnalyticsListener(this);
fun dispose() {
abandonAudioFocus()
player.removeAnalyticsListener(this)
}

/*//////////////////////////////////////////////////////////////////////////
// Audio Manager
//////////////////////////////////////////////////////////////////////////*/
public void requestAudioFocus() {
AudioManagerCompat.requestAudioFocus(audioManager, request);
////////////////////////////////////////////////////////////////////////// */
fun requestAudioFocus() {
AudioManagerCompat.requestAudioFocus(audioManager, request)
}

public void abandonAudioFocus() {
AudioManagerCompat.abandonAudioFocusRequest(audioManager, request);
fun abandonAudioFocus() {
AudioManagerCompat.abandonAudioFocusRequest(audioManager, request)
}

public int getVolume() {
return audioManager.getStreamVolume(STREAM_TYPE);
}
public void setVolume(final int volume) {
audioManager.setStreamVolume(STREAM_TYPE, volume, 0);
}
var volume: Int
get() = audioManager.getStreamVolume(STREAM_TYPE)
set(volume) {
audioManager.setStreamVolume(STREAM_TYPE, volume, 0)
}

public int getMaxVolume() {
return AudioManagerCompat.getStreamMaxVolume(audioManager, STREAM_TYPE);
}
val maxVolume: Int
get() = AudioManagerCompat.getStreamMaxVolume(audioManager, STREAM_TYPE)

/*//////////////////////////////////////////////////////////////////////////
// AudioFocus
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onAudioFocusChange(final int focusChange) {
Log.d(TAG, "onAudioFocusChange() called with: focusChange = [" + focusChange + "]");
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
onAudioFocusGain();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
onAudioFocusLossCanDuck();
break;
case AudioManager.AUDIOFOCUS_LOSS:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
onAudioFocusLoss();
break;
////////////////////////////////////////////////////////////////////////// */
override fun onAudioFocusChange(focusChange: Int) {
Log.d(TAG, "onAudioFocusChange() called with: focusChange = [$focusChange]")
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> onAudioFocusGain()
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> onAudioFocusLossCanDuck()
AudioManager.AUDIOFOCUS_LOSS, AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> onAudioFocusLoss()
}
}

private void onAudioFocusGain() {
Log.d(TAG, "onAudioFocusGain() called");
player.setVolume(DUCK_AUDIO_TO);
animateAudio(DUCK_AUDIO_TO, 1.0f);
private fun onAudioFocusGain() {
Log.d(TAG, "onAudioFocusGain() called")
player.volume = DUCK_AUDIO_TO
animateAudio(DUCK_AUDIO_TO, 1.0f)
if (PlayerHelper.isResumeAfterAudioFocusGain(context)) {
player.play();
player.play()
}
}

private void onAudioFocusLoss() {
Log.d(TAG, "onAudioFocusLoss() called");
player.pause();
private fun onAudioFocusLoss() {
Log.d(TAG, "onAudioFocusLoss() called")
player.pause()
}

private void onAudioFocusLossCanDuck() {
Log.d(TAG, "onAudioFocusLossCanDuck() called");
private fun onAudioFocusLossCanDuck() {
Log.d(TAG, "onAudioFocusLossCanDuck() called")
// Set the volume to 1/10 on ducking
player.setVolume(DUCK_AUDIO_TO);
player.volume = DUCK_AUDIO_TO
}

private void animateAudio(final float from, final float to) {
final ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setFloatValues(from, to);
valueAnimator.setDuration(AudioReactor.DUCK_DURATION);
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(final Animator animation) {
player.setVolume(from);
}
@Override
public void onAnimationCancel(final Animator animation) {
player.setVolume(to);
}
@Override
public void onAnimationEnd(final Animator animation) {
player.setVolume(to);
}
});
valueAnimator.addUpdateListener(animation ->
player.setVolume(((float) animation.getAnimatedValue())));
valueAnimator.start();
private fun animateAudio(from: Float, to: Float) {
val valueAnimator = ValueAnimator()
valueAnimator.setFloatValues(from, to)
valueAnimator.duration = DUCK_DURATION.toLong()
valueAnimator.addListener(
onStart = { player.volume = from },
onCancel = { player.volume = to },
onEnd = { player.volume = to }
)
valueAnimator.addUpdateListener { animation: ValueAnimator ->
player.volume = animation.animatedValue as Float
}
valueAnimator.start()
}

/*//////////////////////////////////////////////////////////////////////////
// Audio Processing
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onAudioSessionId(final EventTime eventTime, final int audioSessionId) {
////////////////////////////////////////////////////////////////////////// */
override fun onAudioSessionId(eventTime: EventTime, audioSessionId: Int) {
if (!PlayerHelper.isUsingDSP()) {
return;
return
}
val intent = Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)
intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioSessionId)
intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
context.sendBroadcast(intent)
}

final Intent intent = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioSessionId);
intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName());
context.sendBroadcast(intent);
companion object {
private const val TAG = "AudioFocusReactor"
private const val DUCK_DURATION = 1500
private const val DUCK_AUDIO_TO = .2f
private const val FOCUS_GAIN_TYPE = AudioManagerCompat.AUDIOFOCUS_GAIN
private const val STREAM_TYPE = AudioManager.STREAM_MUSIC
}
}

0 comments on commit c29b3be

Please sign in to comment.