From e5a2cea6b0464cdf16018351bff30b06486d264b Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 11 Dec 2018 13:03:44 -0800 Subject: [PATCH] Fix voice note seeking issue. On some devices, pausing+resuming (or seeking) would restart playback from the beginning, but show a progress bar further up. This seems to have been caused by same race condition-y thing where we were seeking multiple times in rapid succession. Now we'll only play once, and things seem to be fine now. Also removed usage of some deprecated methods. Fixes #8432 --- .../securesms/audio/AudioSlidePlayer.java | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/org/thoughtcrime/securesms/audio/AudioSlidePlayer.java b/src/org/thoughtcrime/securesms/audio/AudioSlidePlayer.java index f523b6cd46..66d46dd218 100644 --- a/src/org/thoughtcrime/securesms/audio/AudioSlidePlayer.java +++ b/src/org/thoughtcrime/securesms/audio/AudioSlidePlayer.java @@ -17,6 +17,7 @@ import android.support.annotation.Nullable; import android.util.Pair; import android.widget.Toast; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.ExoPlaybackException; @@ -25,6 +26,7 @@ import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.LoadControl; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; import com.google.android.exoplayer2.source.ExtractorMediaSource; import com.google.android.exoplayer2.source.MediaSource; @@ -109,17 +111,30 @@ public class AudioSlidePlayer implements SensorEventListener { mediaPlayer.prepare(createMediaSource(audioAttachmentServer.getUri())); mediaPlayer.setPlayWhenReady(true); - mediaPlayer.setAudioStreamType(earpiece ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC); - mediaPlayer.addListener(new Player.DefaultEventListener() { + mediaPlayer.setAudioAttributes(new AudioAttributes.Builder() + .setContentType(earpiece ? C.CONTENT_TYPE_SPEECH : C.CONTENT_TYPE_MUSIC) + .setUsage(earpiece ? C.USAGE_VOICE_COMMUNICATION : C.USAGE_MEDIA) + .build()); + mediaPlayer.addListener(new Player.EventListener() { + + boolean started = false; @Override public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { + Log.d(TAG, "onPlayerStateChanged(" + playWhenReady + ", " + playbackState + ")"); switch (playbackState) { case Player.STATE_READY: - Log.w(TAG, "onPrepared"); + Log.i(TAG, "onPrepared() " + mediaPlayer.getBufferedPercentage() + "% buffered"); synchronized (AudioSlidePlayer.this) { if (mediaPlayer == null) return; + if (started) { + Log.d(TAG, "Already started. Ignoring."); + return; + } + + started = true; + if (progress > 0) { mediaPlayer.seekTo((long) (mediaPlayer.getDuration() * progress)); } @@ -134,7 +149,7 @@ public class AudioSlidePlayer implements SensorEventListener { break; case Player.STATE_ENDED: - Log.w(TAG, "onComplete"); + Log.i(TAG, "onComplete"); synchronized (AudioSlidePlayer.this) { mediaPlayer = null; @@ -336,9 +351,9 @@ public class AudioSlidePlayer implements SensorEventListener { } public interface Listener { - public void onStart(); - public void onStop(); - public void onProgress(double progress, long millis); + void onStart(); + void onStop(); + void onProgress(double progress, long millis); } private static class ProgressEventHandler extends Handler { @@ -353,7 +368,7 @@ public class AudioSlidePlayer implements SensorEventListener { public void handleMessage(Message msg) { AudioSlidePlayer player = playerReference.get(); - if (player == null || player.mediaPlayer == null || player.mediaPlayer.getPlaybackState() != ExoPlayer.STATE_READY) { + if (player == null || player.mediaPlayer == null || !isPlayerActive(player.mediaPlayer)) { return; } @@ -361,5 +376,9 @@ public class AudioSlidePlayer implements SensorEventListener { player.notifyOnProgress(progress.first, progress.second); sendEmptyMessageDelayed(0, 50); } + + private boolean isPlayerActive(@NonNull SimpleExoPlayer player) { + return player.getPlaybackState() == Player.STATE_READY || player.getPlaybackState() == Player.STATE_BUFFERING; + } } }