61
61
import androidx .media3 .effect .DefaultVideoFrameProcessor ;
62
62
import androidx .media3 .effect .SingleInputVideoGraph ;
63
63
import androidx .media3 .effect .TimestampAdjustment ;
64
+ import androidx .media3 .exoplayer .DefaultLoadControl ;
64
65
import androidx .media3 .exoplayer .ExoPlayer ;
66
+ import androidx .media3 .exoplayer .LoadControl ;
65
67
import androidx .media3 .exoplayer .RendererCapabilities ;
66
68
import androidx .media3 .exoplayer .RendererCapabilities .Capabilities ;
67
69
import androidx .media3 .exoplayer .analytics .AnalyticsCollector ;
@@ -130,6 +132,7 @@ public static final class Builder {
130
132
private VideoGraph .@ MonotonicNonNull Factory videoGraphFactory ;
131
133
132
134
private @ MonotonicNonNull GlObjectsProvider glObjectsProvider ;
135
+ private LoadControl loadControl ;
133
136
private boolean enableReplayableCache ;
134
137
private long lateThresholdToDropInputUs ;
135
138
private boolean built ;
@@ -148,6 +151,7 @@ public Builder(Context context) {
148
151
.setMaxOutputSize (GlUtil .MAX_BITMAP_DECODING_SIZE );
149
152
videoPrewarmingEnabled = true ;
150
153
lateThresholdToDropInputUs = LATE_US_TO_DROP_INPUT_FRAME ;
154
+ loadControl = new DefaultLoadControl ();
151
155
clock = Clock .DEFAULT ;
152
156
}
153
157
@@ -290,6 +294,21 @@ public Builder setGlObjectsProvider(GlObjectsProvider glObjectsProvider) {
290
294
return this ;
291
295
}
292
296
297
+ /**
298
+ * Sets the {@link LoadControl} that will be used by the player to control buffering of all
299
+ * {@linkplain EditedMediaItem#mediaItem media items} in a {@link Composition}.
300
+ *
301
+ * <p>By default, a {@link DefaultLoadControl} is used.
302
+ *
303
+ * @param loadControl A {@link LoadControl}.
304
+ * @return This builder, for convenience.
305
+ */
306
+ @ CanIgnoreReturnValue
307
+ public Builder setLoadControl (LoadControl loadControl ) {
308
+ this .loadControl = loadControl ;
309
+ return this ;
310
+ }
311
+
293
312
/**
294
313
* Sets whether to enable replayable cache.
295
314
*
@@ -402,6 +421,7 @@ public CompositionPlayer build() {
402
421
private final VideoGraph .Factory videoGraphFactory ;
403
422
private final boolean videoPrewarmingEnabled ;
404
423
private final HandlerWrapper compositionInternalListenerHandler ;
424
+ private final LoadControl loadControl ;
405
425
private final boolean enableReplayableCache ;
406
426
private final long lateThresholdToDropInputUs ;
407
427
@@ -454,6 +474,7 @@ private CompositionPlayer(Builder builder) {
454
474
videoGraphFactory = checkNotNull (builder .videoGraphFactory );
455
475
videoPrewarmingEnabled = builder .videoPrewarmingEnabled ;
456
476
compositionInternalListenerHandler = clock .createHandler (builder .looper , /* callback= */ null );
477
+ loadControl = builder .loadControl ;
457
478
this .enableReplayableCache = builder .enableReplayableCache ;
458
479
lateThresholdToDropInputUs = builder .lateThresholdToDropInputUs ;
459
480
videoTracksSelected = new SparseBooleanArray ();
@@ -1477,6 +1498,7 @@ private SequencePlayerHolder(
1477
1498
.setPlaybackLooper (playbackLooper )
1478
1499
.setRenderersFactory (renderersFactory )
1479
1500
.setHandleAudioBecomingNoisy (true )
1501
+ .setLoadControl (loadControl )
1480
1502
.setClock (clock )
1481
1503
// Use dynamic scheduling to show the first video/image frame more promptly when the
1482
1504
// player is paused (which is common in editing applications).
0 commit comments