|
11 | 11 | import androidx.media3.common.C;
|
12 | 12 | import androidx.media3.exoplayer.DefaultLivePlaybackSpeedControl;
|
13 | 13 | import androidx.media3.exoplayer.DefaultLoadControl;
|
| 14 | +import androidx.media3.exoplayer.DefaultRenderersFactory; |
14 | 15 | import androidx.media3.exoplayer.ExoPlaybackException;
|
15 | 16 | import androidx.media3.exoplayer.LivePlaybackSpeedControl;
|
16 | 17 | import androidx.media3.exoplayer.LoadControl;
|
|
25 | 26 | import androidx.media3.common.TrackSelectionParameters;
|
26 | 27 | import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences;
|
27 | 28 | import androidx.media3.common.AudioAttributes;
|
| 29 | +import androidx.media3.exoplayer.NoSampleRenderer; |
| 30 | +import androidx.media3.exoplayer.Renderer; |
| 31 | +import androidx.media3.exoplayer.RenderersFactory; |
28 | 32 | import androidx.media3.extractor.DefaultExtractorsFactory;
|
29 | 33 | import androidx.media3.common.Metadata;
|
30 | 34 | import androidx.media3.exoplayer.metadata.MetadataOutput;
|
@@ -250,7 +254,9 @@ public void onTracksChanged(Tracks tracks) {
|
250 | 254 | }
|
251 | 255 |
|
252 | 256 | private boolean updatePositionIfChanged() {
|
253 |
| - if (getCurrentPosition() == updatePosition) return false; |
| 257 | + if (!player.getPlayWhenReady() || processingState != ProcessingState.ready) { |
| 258 | + if (getCurrentPosition() == updatePosition) return false; |
| 259 | + } |
254 | 260 | updatePosition = getCurrentPosition();
|
255 | 261 | updateTime = System.currentTimeMillis();
|
256 | 262 | return true;
|
@@ -749,7 +755,14 @@ private void load(final List<MediaSource> mediaSources, ShuffleOrder shuffleOrde
|
749 | 755 |
|
750 | 756 | private void ensurePlayerInitialized() {
|
751 | 757 | if (player == null) {
|
752 |
| - ExoPlayer.Builder builder = new ExoPlayer.Builder(context); |
| 758 | + RenderersFactory renderersFactory = (eventHandler, videoListener, audioListener, textOutput, metadataOutput) -> { |
| 759 | + Renderer[] defaultRenderers = new DefaultRenderersFactory(context) |
| 760 | + .createRenderers(eventHandler, videoListener, audioListener, textOutput, metadataOutput); |
| 761 | + Renderer[] allRenderers = Arrays.copyOf(defaultRenderers, defaultRenderers.length + 1); |
| 762 | + allRenderers[defaultRenderers.length] = new ObserverRenderer(); |
| 763 | + return allRenderers; |
| 764 | + }; |
| 765 | + ExoPlayer.Builder builder = new ExoPlayer.Builder(context, renderersFactory); |
753 | 766 | builder.setUseLazyPreparation(useLazyPreparation);
|
754 | 767 | if (loadControl != null) {
|
755 | 768 | builder.setLoadControl(loadControl);
|
@@ -1103,4 +1116,31 @@ enum ProcessingState {
|
1103 | 1116 | ready,
|
1104 | 1117 | completed
|
1105 | 1118 | }
|
| 1119 | + |
| 1120 | + public class ObserverRenderer extends NoSampleRenderer { |
| 1121 | + private long lastPosUs = 0L; |
| 1122 | + private int consecutivePosCount = 0; |
| 1123 | + |
| 1124 | + @Override |
| 1125 | + public void render(long positionUs, long elapsedRealtimeUs) { |
| 1126 | + if (positionUs == lastPosUs) { |
| 1127 | + consecutivePosCount++; |
| 1128 | + } else { |
| 1129 | + if (consecutivePosCount >= 3) { |
| 1130 | + handler.post(() -> { |
| 1131 | + if (updatePositionIfChanged()) { |
| 1132 | + broadcastImmediatePlaybackEvent(); |
| 1133 | + } |
| 1134 | + }); |
| 1135 | + } |
| 1136 | + consecutivePosCount = 0; |
| 1137 | + } |
| 1138 | + lastPosUs = positionUs; |
| 1139 | + } |
| 1140 | + |
| 1141 | + @Override |
| 1142 | + public String getName() { |
| 1143 | + return "ObserverRenderer"; |
| 1144 | + } |
| 1145 | + } |
1106 | 1146 | }
|
0 commit comments