Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions app/src/main/java/org/schabi/newpipe/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,15 @@ private void initPlayer(final boolean playOnReady) {
simpleExoPlayer.setWakeMode(C.WAKE_MODE_NETWORK);
simpleExoPlayer.setHandleAudioBecomingNoisy(true);

// Enable automatic audio focus management - let Android handle ducking automatically
simpleExoPlayer.setAudioAttributes(
new com.google.android.exoplayer2.audio.AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.AUDIO_CONTENT_TYPE_MUSIC)
.build(),
true // handleAudioFocus = true for automatic management
);

audioReactor = new AudioReactor(context, simpleExoPlayer);

registerBroadcastReceiver();
Expand Down Expand Up @@ -1190,10 +1199,6 @@ private void onPrepared(final boolean playWhenReady) {
}

UIs.call(PlayerUi::onPrepared);

if (playWhenReady && !isMuted()) {
audioReactor.requestAudioFocus();
}
}

private void onBlocked() {
Expand Down Expand Up @@ -1341,11 +1346,6 @@ public void toggleShuffleModeEnabled() {
public void toggleMute() {
final boolean wasMuted = isMuted();
simpleExoPlayer.setVolume(wasMuted ? 1 : 0);
if (wasMuted) {
audioReactor.requestAudioFocus();
} else {
audioReactor.abandonAudioFocus();
}
Comment on lines -1344 to -1348
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change breaks the mute functionality. IT is not possible anymore to play audio in a different app and watch a video simultaneously.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reply. I'll figure it out.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TobiGr
I fixed it. Could you review it again please?
Thanks!!

UIs.call(playerUi -> playerUi.onMuteUnmuteChanged(!wasMuted));
notifyPlaybackUpdateToListeners();
}
Expand Down Expand Up @@ -1757,10 +1757,6 @@ public void play() {
return;
}

if (!isMuted()) {
audioReactor.requestAudioFocus();
}

if (currentState == STATE_COMPLETED) {
if (playQueue.getIndex() == 0) {
seekToDefault();
Expand All @@ -1781,7 +1777,6 @@ public void pause() {
return;
}

audioReactor.abandonAudioFocus();
simpleExoPlayer.pause();
saveStreamProgressState();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,36 @@
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.ExoPlayer;
import com.google.android.exoplayer2.analytics.AnalyticsListener;

public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, AnalyticsListener {
public class AudioReactor implements 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 ExoPlayer player;
private final Context context;
private final AudioManager audioManager;

private final AudioFocusRequestCompat request;

public AudioReactor(@NonNull final Context context,
@NonNull final ExoPlayer 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();
}

public void dispose() {
abandonAudioFocus();
player.removeAnalyticsListener(this);
notifyAudioSessionUpdate(false, player.getAudioSessionId());
}
Expand All @@ -57,14 +39,6 @@ public void dispose() {
// Audio Manager
//////////////////////////////////////////////////////////////////////////*/

public void requestAudioFocus() {
AudioManagerCompat.requestAudioFocus(audioManager, request);
}

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

public int getVolume() {
return audioManager.getStreamVolume(STREAM_TYPE);
}
Expand All @@ -77,73 +51,6 @@ public int getMaxVolume() {
return 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;
}
}

private void onAudioFocusGain() {
Log.d(TAG, "onAudioFocusGain() called");
player.setVolume(DUCK_AUDIO_TO);
animateAudio(DUCK_AUDIO_TO, 1.0f);

if (PlayerHelper.isResumeAfterAudioFocusGain(context)) {
player.play();
}
}

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

private void onAudioFocusLossCanDuck() {
Log.d(TAG, "onAudioFocusLossCanDuck() called");
// Set the volume to 1/10 on ducking
player.setVolume(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();
}

/*//////////////////////////////////////////////////////////////////////////
// Audio Processing
//////////////////////////////////////////////////////////////////////////*/
Expand Down
Loading