Simplify DefaultLoadControl
DefaultLoadControl applies the same min buffer duration to audio and video. By default, min buffer is set equal to max buffer (50 seconds). PiperOrigin-RevId: 297324489
This commit is contained in:
parent
31f0302505
commit
f34930ab0d
@ -3,6 +3,9 @@
|
|||||||
### dev-v2 (not yet released) ###
|
### dev-v2 (not yet released) ###
|
||||||
|
|
||||||
* Core library:
|
* Core library:
|
||||||
|
* The `DefaultLoadControl` default minimum buffer is set to 50 seconds,
|
||||||
|
equal to the default maximum buffer. `DefaultLoadControl` applies the
|
||||||
|
same behavior for audio and video.
|
||||||
* Add API in `AnalyticsListener` to report video frame processing offset.
|
* Add API in `AnalyticsListener` to report video frame processing offset.
|
||||||
`MediaCodecVideoRenderer` reports the event.
|
`MediaCodecVideoRenderer` reports the event.
|
||||||
* Add fields `videoFrameProcessingOffsetUsSum` and
|
* Add fields `videoFrameProcessingOffsetUsSum` and
|
||||||
|
@ -29,14 +29,12 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The default minimum duration of media that the player will attempt to ensure is buffered at all
|
* The default minimum duration of media that the player will attempt to ensure is buffered at all
|
||||||
* times, in milliseconds. This value is only applied to playbacks without video.
|
* times, in milliseconds.
|
||||||
*/
|
*/
|
||||||
public static final int DEFAULT_MIN_BUFFER_MS = 15000;
|
public static final int DEFAULT_MIN_BUFFER_MS = 50000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default maximum duration of media that the player will attempt to buffer, in milliseconds.
|
* The default maximum duration of media that the player will attempt to buffer, in milliseconds.
|
||||||
* For playbacks with video, this is also the default minimum duration of media that the player
|
|
||||||
* will attempt to ensure is buffered.
|
|
||||||
*/
|
*/
|
||||||
public static final int DEFAULT_MAX_BUFFER_MS = 50000;
|
public static final int DEFAULT_MAX_BUFFER_MS = 50000;
|
||||||
|
|
||||||
@ -90,8 +88,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private DefaultAllocator allocator;
|
private DefaultAllocator allocator;
|
||||||
private int minBufferAudioMs;
|
private int minBufferMs;
|
||||||
private int minBufferVideoMs;
|
|
||||||
private int maxBufferMs;
|
private int maxBufferMs;
|
||||||
private int bufferForPlaybackMs;
|
private int bufferForPlaybackMs;
|
||||||
private int bufferForPlaybackAfterRebufferMs;
|
private int bufferForPlaybackAfterRebufferMs;
|
||||||
@ -103,8 +100,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
|
|
||||||
/** Constructs a new instance. */
|
/** Constructs a new instance. */
|
||||||
public Builder() {
|
public Builder() {
|
||||||
minBufferAudioMs = DEFAULT_MIN_BUFFER_MS;
|
minBufferMs = DEFAULT_MIN_BUFFER_MS;
|
||||||
minBufferVideoMs = DEFAULT_MAX_BUFFER_MS;
|
|
||||||
maxBufferMs = DEFAULT_MAX_BUFFER_MS;
|
maxBufferMs = DEFAULT_MAX_BUFFER_MS;
|
||||||
bufferForPlaybackMs = DEFAULT_BUFFER_FOR_PLAYBACK_MS;
|
bufferForPlaybackMs = DEFAULT_BUFFER_FOR_PLAYBACK_MS;
|
||||||
bufferForPlaybackAfterRebufferMs = DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
bufferForPlaybackAfterRebufferMs = DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
||||||
@ -158,8 +154,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
"minBufferMs",
|
"minBufferMs",
|
||||||
"bufferForPlaybackAfterRebufferMs");
|
"bufferForPlaybackAfterRebufferMs");
|
||||||
assertGreaterOrEqual(maxBufferMs, minBufferMs, "maxBufferMs", "minBufferMs");
|
assertGreaterOrEqual(maxBufferMs, minBufferMs, "maxBufferMs", "minBufferMs");
|
||||||
this.minBufferAudioMs = minBufferMs;
|
this.minBufferMs = minBufferMs;
|
||||||
this.minBufferVideoMs = minBufferMs;
|
|
||||||
this.maxBufferMs = maxBufferMs;
|
this.maxBufferMs = maxBufferMs;
|
||||||
this.bufferForPlaybackMs = bufferForPlaybackMs;
|
this.bufferForPlaybackMs = bufferForPlaybackMs;
|
||||||
this.bufferForPlaybackAfterRebufferMs = bufferForPlaybackAfterRebufferMs;
|
this.bufferForPlaybackAfterRebufferMs = bufferForPlaybackAfterRebufferMs;
|
||||||
@ -222,8 +217,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
}
|
}
|
||||||
return new DefaultLoadControl(
|
return new DefaultLoadControl(
|
||||||
allocator,
|
allocator,
|
||||||
minBufferAudioMs,
|
minBufferMs,
|
||||||
minBufferVideoMs,
|
|
||||||
maxBufferMs,
|
maxBufferMs,
|
||||||
bufferForPlaybackMs,
|
bufferForPlaybackMs,
|
||||||
bufferForPlaybackAfterRebufferMs,
|
bufferForPlaybackAfterRebufferMs,
|
||||||
@ -236,8 +230,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
|
|
||||||
private final DefaultAllocator allocator;
|
private final DefaultAllocator allocator;
|
||||||
|
|
||||||
private final long minBufferAudioUs;
|
private final long minBufferUs;
|
||||||
private final long minBufferVideoUs;
|
|
||||||
private final long maxBufferUs;
|
private final long maxBufferUs;
|
||||||
private final long bufferForPlaybackUs;
|
private final long bufferForPlaybackUs;
|
||||||
private final long bufferForPlaybackAfterRebufferUs;
|
private final long bufferForPlaybackAfterRebufferUs;
|
||||||
@ -248,7 +241,6 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
|
|
||||||
private int targetBufferBytes;
|
private int targetBufferBytes;
|
||||||
private boolean isBuffering;
|
private boolean isBuffering;
|
||||||
private boolean hasVideo;
|
|
||||||
|
|
||||||
/** Constructs a new instance, using the {@code DEFAULT_*} constants defined in this class. */
|
/** Constructs a new instance, using the {@code DEFAULT_*} constants defined in this class. */
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@ -261,8 +253,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
public DefaultLoadControl(DefaultAllocator allocator) {
|
public DefaultLoadControl(DefaultAllocator allocator) {
|
||||||
this(
|
this(
|
||||||
allocator,
|
allocator,
|
||||||
/* minBufferAudioMs= */ DEFAULT_MIN_BUFFER_MS,
|
DEFAULT_MIN_BUFFER_MS,
|
||||||
/* minBufferVideoMs= */ DEFAULT_MAX_BUFFER_MS,
|
|
||||||
DEFAULT_MAX_BUFFER_MS,
|
DEFAULT_MAX_BUFFER_MS,
|
||||||
DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
||||||
DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS,
|
DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS,
|
||||||
@ -284,8 +275,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
boolean prioritizeTimeOverSizeThresholds) {
|
boolean prioritizeTimeOverSizeThresholds) {
|
||||||
this(
|
this(
|
||||||
allocator,
|
allocator,
|
||||||
/* minBufferAudioMs= */ minBufferMs,
|
minBufferMs,
|
||||||
/* minBufferVideoMs= */ minBufferMs,
|
|
||||||
maxBufferMs,
|
maxBufferMs,
|
||||||
bufferForPlaybackMs,
|
bufferForPlaybackMs,
|
||||||
bufferForPlaybackAfterRebufferMs,
|
bufferForPlaybackAfterRebufferMs,
|
||||||
@ -297,8 +287,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
|
|
||||||
protected DefaultLoadControl(
|
protected DefaultLoadControl(
|
||||||
DefaultAllocator allocator,
|
DefaultAllocator allocator,
|
||||||
int minBufferAudioMs,
|
int minBufferMs,
|
||||||
int minBufferVideoMs,
|
|
||||||
int maxBufferMs,
|
int maxBufferMs,
|
||||||
int bufferForPlaybackMs,
|
int bufferForPlaybackMs,
|
||||||
int bufferForPlaybackAfterRebufferMs,
|
int bufferForPlaybackAfterRebufferMs,
|
||||||
@ -309,27 +298,17 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
assertGreaterOrEqual(bufferForPlaybackMs, 0, "bufferForPlaybackMs", "0");
|
assertGreaterOrEqual(bufferForPlaybackMs, 0, "bufferForPlaybackMs", "0");
|
||||||
assertGreaterOrEqual(
|
assertGreaterOrEqual(
|
||||||
bufferForPlaybackAfterRebufferMs, 0, "bufferForPlaybackAfterRebufferMs", "0");
|
bufferForPlaybackAfterRebufferMs, 0, "bufferForPlaybackAfterRebufferMs", "0");
|
||||||
|
assertGreaterOrEqual(minBufferMs, bufferForPlaybackMs, "minBufferMs", "bufferForPlaybackMs");
|
||||||
assertGreaterOrEqual(
|
assertGreaterOrEqual(
|
||||||
minBufferAudioMs, bufferForPlaybackMs, "minBufferAudioMs", "bufferForPlaybackMs");
|
minBufferMs,
|
||||||
assertGreaterOrEqual(
|
|
||||||
minBufferVideoMs, bufferForPlaybackMs, "minBufferVideoMs", "bufferForPlaybackMs");
|
|
||||||
assertGreaterOrEqual(
|
|
||||||
minBufferAudioMs,
|
|
||||||
bufferForPlaybackAfterRebufferMs,
|
bufferForPlaybackAfterRebufferMs,
|
||||||
"minBufferAudioMs",
|
"minBufferMs",
|
||||||
"bufferForPlaybackAfterRebufferMs");
|
"bufferForPlaybackAfterRebufferMs");
|
||||||
assertGreaterOrEqual(
|
assertGreaterOrEqual(maxBufferMs, minBufferMs, "maxBufferMs", "minBufferMs");
|
||||||
minBufferVideoMs,
|
|
||||||
bufferForPlaybackAfterRebufferMs,
|
|
||||||
"minBufferVideoMs",
|
|
||||||
"bufferForPlaybackAfterRebufferMs");
|
|
||||||
assertGreaterOrEqual(maxBufferMs, minBufferAudioMs, "maxBufferMs", "minBufferAudioMs");
|
|
||||||
assertGreaterOrEqual(maxBufferMs, minBufferVideoMs, "maxBufferMs", "minBufferVideoMs");
|
|
||||||
assertGreaterOrEqual(backBufferDurationMs, 0, "backBufferDurationMs", "0");
|
assertGreaterOrEqual(backBufferDurationMs, 0, "backBufferDurationMs", "0");
|
||||||
|
|
||||||
this.allocator = allocator;
|
this.allocator = allocator;
|
||||||
this.minBufferAudioUs = C.msToUs(minBufferAudioMs);
|
this.minBufferUs = C.msToUs(minBufferMs);
|
||||||
this.minBufferVideoUs = C.msToUs(minBufferVideoMs);
|
|
||||||
this.maxBufferUs = C.msToUs(maxBufferMs);
|
this.maxBufferUs = C.msToUs(maxBufferMs);
|
||||||
this.bufferForPlaybackUs = C.msToUs(bufferForPlaybackMs);
|
this.bufferForPlaybackUs = C.msToUs(bufferForPlaybackMs);
|
||||||
this.bufferForPlaybackAfterRebufferUs = C.msToUs(bufferForPlaybackAfterRebufferMs);
|
this.bufferForPlaybackAfterRebufferUs = C.msToUs(bufferForPlaybackAfterRebufferMs);
|
||||||
@ -351,7 +330,6 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
@Override
|
@Override
|
||||||
public void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
|
public void onTracksSelected(Renderer[] renderers, TrackGroupArray trackGroups,
|
||||||
TrackSelectionArray trackSelections) {
|
TrackSelectionArray trackSelections) {
|
||||||
hasVideo = hasVideo(renderers, trackSelections);
|
|
||||||
targetBufferBytes =
|
targetBufferBytes =
|
||||||
targetBufferBytesOverwrite == C.LENGTH_UNSET
|
targetBufferBytesOverwrite == C.LENGTH_UNSET
|
||||||
? calculateTargetBufferBytes(renderers, trackSelections)
|
? calculateTargetBufferBytes(renderers, trackSelections)
|
||||||
@ -387,7 +365,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
@Override
|
@Override
|
||||||
public boolean shouldContinueLoading(long bufferedDurationUs, float playbackSpeed) {
|
public boolean shouldContinueLoading(long bufferedDurationUs, float playbackSpeed) {
|
||||||
boolean targetBufferSizeReached = allocator.getTotalBytesAllocated() >= targetBufferBytes;
|
boolean targetBufferSizeReached = allocator.getTotalBytesAllocated() >= targetBufferBytes;
|
||||||
long minBufferUs = hasVideo ? minBufferVideoUs : minBufferAudioUs;
|
long minBufferUs = this.minBufferUs;
|
||||||
if (playbackSpeed > 1) {
|
if (playbackSpeed > 1) {
|
||||||
// The playback speed is faster than real time, so scale up the minimum required media
|
// The playback speed is faster than real time, so scale up the minimum required media
|
||||||
// duration to keep enough media buffered for a playout duration of minBufferUs.
|
// duration to keep enough media buffered for a playout duration of minBufferUs.
|
||||||
@ -467,15 +445,6 @@ public class DefaultLoadControl implements LoadControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasVideo(Renderer[] renderers, TrackSelectionArray trackSelectionArray) {
|
|
||||||
for (int i = 0; i < renderers.length; i++) {
|
|
||||||
if (renderers[i].getTrackType() == C.TRACK_TYPE_VIDEO && trackSelectionArray.get(i) != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void assertGreaterOrEqual(int value1, int value2, String name1, String name2) {
|
private static void assertGreaterOrEqual(int value1, int value2, String name1, String name2) {
|
||||||
Assertions.checkArgument(value1 >= value2, name1 + " cannot be less than " + name2);
|
Assertions.checkArgument(value1 >= value2, name1 + " cannot be less than " + name2);
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ import org.junit.runner.RunWith;
|
|||||||
public class DefaultLoadControlTest {
|
public class DefaultLoadControlTest {
|
||||||
|
|
||||||
private static final float SPEED = 1f;
|
private static final float SPEED = 1f;
|
||||||
private static final long MIN_BUFFER_US = C.msToUs(DefaultLoadControl.DEFAULT_MIN_BUFFER_MS);
|
|
||||||
private static final long MAX_BUFFER_US = C.msToUs(DefaultLoadControl.DEFAULT_MAX_BUFFER_MS);
|
private static final long MAX_BUFFER_US = C.msToUs(DefaultLoadControl.DEFAULT_MAX_BUFFER_MS);
|
||||||
|
private static final long MIN_BUFFER_US = MAX_BUFFER_US / 2;
|
||||||
private static final int TARGET_BUFFER_BYTES = C.DEFAULT_BUFFER_SEGMENT_SIZE * 2;
|
private static final int TARGET_BUFFER_BYTES = C.DEFAULT_BUFFER_SEGMENT_SIZE * 2;
|
||||||
|
|
||||||
private Builder builder;
|
private Builder builder;
|
||||||
@ -48,16 +48,20 @@ public class DefaultLoadControlTest {
|
|||||||
createDefaultLoadControl();
|
createDefaultLoadControl();
|
||||||
|
|
||||||
assertThat(loadControl.shouldContinueLoading(/* bufferedDurationUs= */ 0, SPEED)).isTrue();
|
assertThat(loadControl.shouldContinueLoading(/* bufferedDurationUs= */ 0, SPEED)).isTrue();
|
||||||
assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US, SPEED)).isTrue();
|
|
||||||
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US - 1, SPEED)).isTrue();
|
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US - 1, SPEED)).isTrue();
|
||||||
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US, SPEED)).isFalse();
|
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US, SPEED)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotContinueLoadingOnceBufferingStopped_untilBelowMinBuffer() {
|
public void shouldNotContinueLoadingOnceBufferingStopped_untilBelowMinBuffer() {
|
||||||
|
builder.setBufferDurationsMs(
|
||||||
|
/* minBufferMs= */ (int) C.usToMs(MIN_BUFFER_US),
|
||||||
|
/* maxBufferMs= */ (int) C.usToMs(MAX_BUFFER_US),
|
||||||
|
/* bufferForPlaybackMs= */ 0,
|
||||||
|
/* bufferForPlaybackAfterRebufferMs= */ 0);
|
||||||
createDefaultLoadControl();
|
createDefaultLoadControl();
|
||||||
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US, SPEED)).isFalse();
|
|
||||||
|
|
||||||
|
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US, SPEED)).isFalse();
|
||||||
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US - 1, SPEED)).isFalse();
|
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US - 1, SPEED)).isFalse();
|
||||||
assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US, SPEED)).isFalse();
|
assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US, SPEED)).isFalse();
|
||||||
assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US - 1, SPEED)).isTrue();
|
assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US - 1, SPEED)).isTrue();
|
||||||
@ -72,14 +76,19 @@ public class DefaultLoadControlTest {
|
|||||||
/* bufferForPlaybackMs= */ 0,
|
/* bufferForPlaybackMs= */ 0,
|
||||||
/* bufferForPlaybackAfterRebufferMs= */ 0);
|
/* bufferForPlaybackAfterRebufferMs= */ 0);
|
||||||
createDefaultLoadControl();
|
createDefaultLoadControl();
|
||||||
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US, SPEED)).isFalse();
|
|
||||||
|
|
||||||
|
assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US, SPEED)).isFalse();
|
||||||
assertThat(loadControl.shouldContinueLoading(5 * C.MICROS_PER_SECOND, SPEED)).isFalse();
|
assertThat(loadControl.shouldContinueLoading(5 * C.MICROS_PER_SECOND, SPEED)).isFalse();
|
||||||
assertThat(loadControl.shouldContinueLoading(500L, SPEED)).isTrue();
|
assertThat(loadControl.shouldContinueLoading(500L, SPEED)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldContinueLoadingWithTargetBufferBytesReached_untilMinBufferReached() {
|
public void shouldContinueLoadingWithTargetBufferBytesReached_untilMinBufferReached() {
|
||||||
|
builder.setBufferDurationsMs(
|
||||||
|
/* minBufferMs= */ (int) C.usToMs(MIN_BUFFER_US),
|
||||||
|
/* maxBufferMs= */ (int) C.usToMs(MAX_BUFFER_US),
|
||||||
|
/* bufferForPlaybackMs= */ 0,
|
||||||
|
/* bufferForPlaybackAfterRebufferMs= */ 0);
|
||||||
createDefaultLoadControl();
|
createDefaultLoadControl();
|
||||||
makeSureTargetBufferBytesReached();
|
makeSureTargetBufferBytesReached();
|
||||||
|
|
||||||
@ -93,6 +102,7 @@ public class DefaultLoadControlTest {
|
|||||||
public void shouldNeverContinueLoading_ifMaxBufferReachedAndNotPrioritizeTimeOverSize() {
|
public void shouldNeverContinueLoading_ifMaxBufferReachedAndNotPrioritizeTimeOverSize() {
|
||||||
builder.setPrioritizeTimeOverSizeThresholds(false);
|
builder.setPrioritizeTimeOverSizeThresholds(false);
|
||||||
createDefaultLoadControl();
|
createDefaultLoadControl();
|
||||||
|
|
||||||
// Put loadControl in buffering state.
|
// Put loadControl in buffering state.
|
||||||
assertThat(loadControl.shouldContinueLoading(/* bufferedDurationUs= */ 0, SPEED)).isTrue();
|
assertThat(loadControl.shouldContinueLoading(/* bufferedDurationUs= */ 0, SPEED)).isTrue();
|
||||||
makeSureTargetBufferBytesReached();
|
makeSureTargetBufferBytesReached();
|
||||||
@ -105,6 +115,11 @@ public class DefaultLoadControlTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldContinueLoadingWithMinBufferReached_inFastPlayback() {
|
public void shouldContinueLoadingWithMinBufferReached_inFastPlayback() {
|
||||||
|
builder.setBufferDurationsMs(
|
||||||
|
/* minBufferMs= */ (int) C.usToMs(MIN_BUFFER_US),
|
||||||
|
/* maxBufferMs= */ (int) C.usToMs(MAX_BUFFER_US),
|
||||||
|
/* bufferForPlaybackMs= */ 0,
|
||||||
|
/* bufferForPlaybackAfterRebufferMs= */ 0);
|
||||||
createDefaultLoadControl();
|
createDefaultLoadControl();
|
||||||
|
|
||||||
// At normal playback speed, we stop buffering when the buffer reaches the minimum.
|
// At normal playback speed, we stop buffering when the buffer reaches the minimum.
|
||||||
@ -130,8 +145,7 @@ public class DefaultLoadControlTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createDefaultLoadControl() {
|
private void createDefaultLoadControl() {
|
||||||
builder.setAllocator(allocator);
|
builder.setAllocator(allocator).setTargetBufferBytes(TARGET_BUFFER_BYTES);
|
||||||
builder.setTargetBufferBytes(TARGET_BUFFER_BYTES);
|
|
||||||
loadControl = builder.createDefaultLoadControl();
|
loadControl = builder.createDefaultLoadControl();
|
||||||
loadControl.onTracksSelected(new Renderer[0], null, null);
|
loadControl.onTracksSelected(new Renderer[0], null, null);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user