Merge pull request #5525 from ByteHamster/remove-media-listeners

Remove all media listeners and end audio focus when shutting down playback service
This commit is contained in:
ByteHamster 2021-11-06 19:20:18 +01:00 committed by GitHub
commit 1fba4a37fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 20 deletions

View File

@ -73,6 +73,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
private final PlayerLock playerLock; private final PlayerLock playerLock;
private final PlayerExecutor executor; private final PlayerExecutor executor;
private boolean useCallerThread = true; private boolean useCallerThread = true;
private boolean isShutDown = false;
private CountDownLatch seekLatch; private CountDownLatch seekLatch;
@ -719,32 +720,22 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/ */
@Override @Override
public void shutdown() { public void shutdown() {
executor.shutdown();
if (mediaPlayer != null) { if (mediaPlayer != null) {
try { try {
removeMediaPlayerErrorListener(); clearMediaPlayerListeners();
if (mediaPlayer.isPlaying()) { if (mediaPlayer.isPlaying()) {
mediaPlayer.stop(); mediaPlayer.stop();
} }
} catch (Exception ignore) { } } catch (Exception ignore) { }
mediaPlayer.release(); mediaPlayer.release();
mediaPlayer = null;
} }
isShutDown = true;
executor.shutdown();
abandonAudioFocus();
releaseWifiLockIfNecessary(); releaseWifiLockIfNecessary();
} }
private void removeMediaPlayerErrorListener() {
if (mediaPlayer instanceof VideoPlayer) {
VideoPlayer vp = (VideoPlayer) mediaPlayer;
vp.setOnErrorListener((mp, what, extra) -> true);
} else if (mediaPlayer instanceof AudioPlayer) {
AudioPlayer ap = (AudioPlayer) mediaPlayer;
ap.setOnErrorListener((mediaPlayer, i, i1) -> true);
} else if (mediaPlayer instanceof ExoPlayerWrapper) {
ExoPlayerWrapper ap = (ExoPlayerWrapper) mediaPlayer;
ap.setOnErrorListener(message -> { });
}
}
/** /**
* Releases internally used resources. This method should only be called when the object is not used anymore. * Releases internally used resources. This method should only be called when the object is not used anymore.
* This method is executed on an internal executor service. * This method is executed on an internal executor service.
@ -864,10 +855,14 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override @Override
public void onAudioFocusChange(final int focusChange) { public void onAudioFocusChange(final int focusChange) {
if (isShutDown) {
return;
}
if (!PlaybackService.isRunning) { if (!PlaybackService.isRunning) {
abandonAudioFocus(); abandonAudioFocus();
Log.d(TAG, "onAudioFocusChange: PlaybackService is no longer running"); Log.d(TAG, "onAudioFocusChange: PlaybackService is no longer running");
if (focusChange == AudioManager.AUDIOFOCUS_GAIN && pausedBecauseOfTransientAudiofocusLoss) { if (focusChange == AudioManager.AUDIOFOCUS_GAIN && pausedBecauseOfTransientAudiofocusLoss) {
pausedBecauseOfTransientAudiofocusLoss = false;
new PlaybackServiceStarter(context, getPlayable()) new PlaybackServiceStarter(context, getPlayable())
.startWhenPrepared(true) .startWhenPrepared(true)
.streamIfLastWasStream() .streamIfLastWasStream()
@ -1011,9 +1006,9 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
return stream; return stream;
} }
private IPlayer setMediaPlayerListeners(IPlayer mp) { private void setMediaPlayerListeners(IPlayer mp) {
if (mp == null || media == null) { if (mp == null || media == null) {
return mp; return;
} }
if (mp instanceof VideoPlayer) { if (mp instanceof VideoPlayer) {
if (media.getMediaType() != MediaType.VIDEO) { if (media.getMediaType() != MediaType.VIDEO) {
@ -1045,7 +1040,31 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
} else { } else {
Log.w(TAG, "Unknown media player: " + mp); Log.w(TAG, "Unknown media player: " + mp);
} }
return mp; }
private void clearMediaPlayerListeners() {
if (mediaPlayer instanceof VideoPlayer) {
VideoPlayer vp = (VideoPlayer) mediaPlayer;
vp.setOnCompletionListener(x -> { });
vp.setOnSeekCompleteListener(x -> { });
vp.setOnErrorListener((mediaPlayer, i, i1) -> false);
vp.setOnBufferingUpdateListener((mediaPlayer, i) -> { });
vp.setOnInfoListener((mediaPlayer, i, i1) -> false);
} else if (mediaPlayer instanceof AudioPlayer) {
AudioPlayer ap = (AudioPlayer) mediaPlayer;
ap.setOnCompletionListener(x -> { });
ap.setOnSeekCompleteListener(x -> { });
ap.setOnErrorListener((x, y, z) -> false);
ap.setOnBufferingUpdateListener((arg0, percent) -> { });
ap.setOnInfoListener((arg0, what, extra) -> false);
} else if (mediaPlayer instanceof ExoPlayerWrapper) {
ExoPlayerWrapper ap = (ExoPlayerWrapper) mediaPlayer;
ap.setOnCompletionListener(x -> { });
ap.setOnSeekCompleteListener(x -> { });
ap.setOnBufferingUpdateListener((arg0, percent) -> { });
ap.setOnErrorListener(x -> { });
ap.setOnInfoListener((arg0, what, extra) -> false);
}
} }
private final MediaPlayer.OnCompletionListener audioCompletionListener = private final MediaPlayer.OnCompletionListener audioCompletionListener =

View File

@ -350,10 +350,10 @@ public class PlaybackServiceTaskManager {
* Cancels all tasks and shuts down the internal executor service of the PSTM. The object should not be used after * Cancels all tasks and shuts down the internal executor service of the PSTM. The object should not be used after
* execution of this method. * execution of this method.
*/ */
public synchronized void shutdown() { public void shutdown() {
EventBus.getDefault().unregister(this); EventBus.getDefault().unregister(this);
cancelAllTasks(); cancelAllTasks();
schedExecutor.shutdown(); schedExecutor.shutdownNow();
} }
private Runnable useMainThreadIfNecessary(Runnable runnable) { private Runnable useMainThreadIfNecessary(Runnable runnable) {