mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add initial playWhenReady setting and tests
Also includes a new test for a similar logic that already exists for speed changes.
This commit is contained in:
parent
e4b32e4e31
commit
513ebf67b7
@ -1879,7 +1879,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
// The reselection did not change any prepared periods.
|
||||
return;
|
||||
}
|
||||
newTrackSelectorResult = periodHolder.selectTracks(playbackSpeed, playbackInfo.timeline);
|
||||
newTrackSelectorResult =
|
||||
periodHolder.selectTracks(
|
||||
playbackSpeed, playbackInfo.timeline, playbackInfo.playWhenReady);
|
||||
if (periodHolder == queue.getPlayingPeriod()) {
|
||||
newPlayingPeriodTrackSelectorResult = newTrackSelectorResult;
|
||||
}
|
||||
@ -2563,7 +2565,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
if (preloadHolder != null) {
|
||||
checkState(!preloadHolder.prepared);
|
||||
preloadHolder.handlePrepared(
|
||||
mediaClock.getPlaybackParameters().speed, playbackInfo.timeline);
|
||||
mediaClock.getPlaybackParameters().speed,
|
||||
playbackInfo.timeline,
|
||||
playbackInfo.playWhenReady);
|
||||
if (queue.isPreloading(mediaPeriod)) {
|
||||
maybeContinuePreloading();
|
||||
}
|
||||
@ -2575,7 +2579,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
throws ExoPlaybackException {
|
||||
if (!loadingPeriodHolder.prepared) {
|
||||
loadingPeriodHolder.handlePrepared(
|
||||
mediaClock.getPlaybackParameters().speed, playbackInfo.timeline);
|
||||
mediaClock.getPlaybackParameters().speed,
|
||||
playbackInfo.timeline,
|
||||
playbackInfo.playWhenReady);
|
||||
}
|
||||
updateLoadControlTrackSelection(
|
||||
loadingPeriodHolder.info.id,
|
||||
|
@ -203,12 +203,14 @@ import java.io.IOException;
|
||||
*
|
||||
* @param playbackSpeed The current factor by which playback is sped up.
|
||||
* @param timeline The current {@link Timeline}.
|
||||
* @param playWhenReady The current value of whether playback should proceed when ready.
|
||||
* @throws ExoPlaybackException If an error occurs during track selection.
|
||||
*/
|
||||
public void handlePrepared(float playbackSpeed, Timeline timeline) throws ExoPlaybackException {
|
||||
public void handlePrepared(float playbackSpeed, Timeline timeline, boolean playWhenReady)
|
||||
throws ExoPlaybackException {
|
||||
prepared = true;
|
||||
trackGroups = mediaPeriod.getTrackGroups();
|
||||
TrackSelectorResult selectorResult = selectTracks(playbackSpeed, timeline);
|
||||
TrackSelectorResult selectorResult = selectTracks(playbackSpeed, timeline, playWhenReady);
|
||||
long requestedStartPositionUs = info.startPositionUs;
|
||||
if (info.durationUs != C.TIME_UNSET && requestedStartPositionUs >= info.durationUs) {
|
||||
// Make sure start position doesn't exceed period duration.
|
||||
@ -254,11 +256,12 @@ import java.io.IOException;
|
||||
*
|
||||
* @param playbackSpeed The current factor by which playback is sped up.
|
||||
* @param timeline The current {@link Timeline}.
|
||||
* @param playWhenReady The current value of whether playback should proceed when ready.
|
||||
* @return The {@link TrackSelectorResult}.
|
||||
* @throws ExoPlaybackException If an error occurs during track selection.
|
||||
*/
|
||||
public TrackSelectorResult selectTracks(float playbackSpeed, Timeline timeline)
|
||||
throws ExoPlaybackException {
|
||||
public TrackSelectorResult selectTracks(
|
||||
float playbackSpeed, Timeline timeline, boolean playWhenReady) throws ExoPlaybackException {
|
||||
TrackSelectorResult selectorResult =
|
||||
trackSelector.selectTracks(rendererCapabilities, getTrackGroups(), info.id, timeline);
|
||||
for (int i = 0; i < selectorResult.length; i++) {
|
||||
@ -273,6 +276,7 @@ import java.io.IOException;
|
||||
for (ExoTrackSelection trackSelection : selectorResult.selections) {
|
||||
if (trackSelection != null) {
|
||||
trackSelection.onPlaybackSpeed(playbackSpeed);
|
||||
trackSelection.onPlayWhenReadyChanged(playWhenReady);
|
||||
}
|
||||
}
|
||||
return selectorResult;
|
||||
|
@ -18,6 +18,7 @@ package androidx.media3.exoplayer.trackselection;
|
||||
import static java.lang.Math.max;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
@ -54,8 +55,8 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
|
||||
// Lazily initialized hashcode.
|
||||
private int hashCode;
|
||||
|
||||
/** The last playWhenReady value when {@link #onPlayWhenReadyChanged(boolean)} was triggered */
|
||||
private boolean lastPlayWhenReady;
|
||||
/** The current value of whether playback will proceed when ready. */
|
||||
private boolean playWhenReady;
|
||||
|
||||
/**
|
||||
* @param group The {@link TrackGroup}. Must not be null.
|
||||
@ -90,7 +91,7 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
|
||||
this.tracks[i] = group.indexOf(formats[i]);
|
||||
}
|
||||
excludeUntilTimes = new long[length];
|
||||
lastPlayWhenReady = false;
|
||||
playWhenReady = false;
|
||||
}
|
||||
|
||||
// TrackSelection implementation.
|
||||
@ -195,13 +196,15 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
|
||||
return excludeUntilTimes[index] > nowMs;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void onPlayWhenReadyChanged(boolean playWhenReady) {
|
||||
lastPlayWhenReady = playWhenReady;
|
||||
this.playWhenReady = playWhenReady;
|
||||
}
|
||||
|
||||
/** Returns whether the playback using this track selection will proceed when ready. */
|
||||
protected final boolean getPlayWhenReady() {
|
||||
return lastPlayWhenReady;
|
||||
return playWhenReady;
|
||||
}
|
||||
|
||||
// Object overrides.
|
||||
|
@ -16174,6 +16174,79 @@ public class ExoPlayerTest {
|
||||
assertThat(deviceVolumeChanged.get()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playWhenReadyChanges_areForwardedToTrackSelection() throws Exception {
|
||||
ArrayList<Boolean> reportedPlayWhenReadyChanges = new ArrayList<>();
|
||||
ArrayList<Boolean> playWhenReadyStatesInTrackSelector = new ArrayList<>();
|
||||
ExoPlayer player =
|
||||
new TestExoPlayerBuilder(context)
|
||||
.setTrackSelector(
|
||||
new FakeTrackSelector(
|
||||
new FakeTrackSelector.FakeTrackSelectionFactory(
|
||||
/* mayReuseTrackSelection= */ false) {
|
||||
@Override
|
||||
protected ExoTrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
return new FakeTrackSelection(trackGroup) {
|
||||
@Override
|
||||
public void onPlayWhenReadyChanged(boolean playWhenReady) {
|
||||
super.onPlayWhenReadyChanged(playWhenReady);
|
||||
reportedPlayWhenReadyChanges.add(playWhenReady);
|
||||
playWhenReadyStatesInTrackSelector.add(getPlayWhenReady());
|
||||
}
|
||||
};
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
player.setMediaSource(
|
||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT));
|
||||
|
||||
player.setPlayWhenReady(true);
|
||||
player.prepare();
|
||||
run(player).untilState(Player.STATE_READY);
|
||||
player.setPlayWhenReady(false);
|
||||
player.setPlayWhenReady(true);
|
||||
run(player).untilPendingCommandsAreFullyHandled();
|
||||
player.release();
|
||||
|
||||
assertThat(reportedPlayWhenReadyChanges).containsExactly(true, false, true).inOrder();
|
||||
assertThat(playWhenReadyStatesInTrackSelector).containsExactly(true, false, true).inOrder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playbackSpeedChanges_areForwardedToTrackSelection() throws Exception {
|
||||
ArrayList<Float> reportedSpeedChanges = new ArrayList<>();
|
||||
ExoPlayer player =
|
||||
new TestExoPlayerBuilder(context)
|
||||
.setTrackSelector(
|
||||
new FakeTrackSelector(
|
||||
new FakeTrackSelector.FakeTrackSelectionFactory(
|
||||
/* mayReuseTrackSelection= */ false) {
|
||||
@Override
|
||||
protected ExoTrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
return new FakeTrackSelection(trackGroup) {
|
||||
@Override
|
||||
public void onPlaybackSpeed(float playbackSpeed) {
|
||||
super.onPlaybackSpeed(playbackSpeed);
|
||||
reportedSpeedChanges.add(playbackSpeed);
|
||||
}
|
||||
};
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
player.setMediaSource(
|
||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT));
|
||||
|
||||
player.setPlaybackSpeed(2f);
|
||||
player.prepare();
|
||||
run(player).untilState(Player.STATE_READY);
|
||||
player.setPlaybackSpeed(1.5f);
|
||||
player.setPlaybackSpeed(1f);
|
||||
run(player).untilPendingCommandsAreFullyHandled();
|
||||
player.release();
|
||||
|
||||
assertThat(reportedSpeedChanges).containsExactly(2f, 1.5f, 1f).inOrder();
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private void addWatchAsSystemFeature() {
|
||||
|
@ -33,7 +33,7 @@ import java.util.List;
|
||||
* of calls to its methods.
|
||||
*/
|
||||
@UnstableApi
|
||||
public final class FakeTrackSelection extends BaseTrackSelection {
|
||||
public class FakeTrackSelection extends BaseTrackSelection {
|
||||
|
||||
private final TrackGroup rendererTrackGroup;
|
||||
private final int selectedIndex;
|
||||
|
@ -50,7 +50,11 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
this(new FakeTrackSelectionFactory(mayReuseTrackSelection));
|
||||
}
|
||||
|
||||
private FakeTrackSelector(FakeTrackSelectionFactory fakeTrackSelectionFactory) {
|
||||
/**
|
||||
* @param fakeTrackSelectionFactory The {@link FakeTrackSelectionFactory} used to create the
|
||||
* {@link FakeTrackSelection} instances.
|
||||
*/
|
||||
public FakeTrackSelector(FakeTrackSelectionFactory fakeTrackSelectionFactory) {
|
||||
super(ApplicationProvider.getApplicationContext(), fakeTrackSelectionFactory);
|
||||
this.fakeTrackSelectionFactory = fakeTrackSelectionFactory;
|
||||
}
|
||||
@ -80,7 +84,11 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
return fakeTrackSelectionFactory.trackSelections;
|
||||
}
|
||||
|
||||
private static class FakeTrackSelectionFactory implements ExoTrackSelection.Factory {
|
||||
/**
|
||||
* A factory for the {@link androidx.media3.test.utils.FakeTrackSelection} instances requested by
|
||||
* the {@link FakeTrackSelector}.
|
||||
*/
|
||||
public static class FakeTrackSelectionFactory implements ExoTrackSelection.Factory {
|
||||
|
||||
private final List<FakeTrackSelection> trackSelections;
|
||||
private final boolean mayReuseTrackSelection;
|
||||
@ -91,7 +99,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExoTrackSelection[] createTrackSelections(
|
||||
public final ExoTrackSelection[] createTrackSelections(
|
||||
ExoTrackSelection.@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
@ -106,7 +114,8 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
||||
return selections;
|
||||
}
|
||||
|
||||
private ExoTrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
/** Creates the {@link FakeTrackSelection} from a {@link TrackGroup}. */
|
||||
protected ExoTrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
if (mayReuseTrackSelection) {
|
||||
for (FakeTrackSelection trackSelection : trackSelections) {
|
||||
if (trackSelection.getTrackGroup().equals(trackGroup)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user