mirror of
https://github.com/androidx/media.git
synced 2025-05-14 11:09:53 +08:00
Return empty track groups and track selections when user seeks to unprepared period
When user seeks to an unprepared period, since there is no period being played, currently the track groups and track selections are still the ones from previous period. This CL changes it so that when such seeking happens, PlaybackInfo's track groups and track selections are changed to empty. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=206916109
This commit is contained in:
parent
45c1e9eef3
commit
0fbe083d4e
@ -47,9 +47,16 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
private static final String TAG = "ExoPlayerImpl";
|
||||
|
||||
/**
|
||||
* This empty track selector result can only be used for {@link PlaybackInfo#trackSelectorResult}
|
||||
* when the player does not have any track selection made (such as when player is reset, or when
|
||||
* player seeks to an unprepared period). It will not be used as result of any {@link
|
||||
* TrackSelector#selectTracks(RendererCapabilities[], TrackGroupArray)} operation.
|
||||
*/
|
||||
/* package */ final TrackSelectorResult emptyTrackSelectorResult;
|
||||
|
||||
private final Renderer[] renderers;
|
||||
private final TrackSelector trackSelector;
|
||||
private final TrackSelectorResult emptyTrackSelectorResult;
|
||||
private final Handler eventHandler;
|
||||
private final ExoPlayerImplInternal internalPlayer;
|
||||
private final Handler internalPlayerHandler;
|
||||
|
@ -700,6 +700,9 @@ import java.util.Collections;
|
||||
maybeContinueLoading();
|
||||
} else {
|
||||
queue.clear(/* keepFrontPeriodUid= */ true);
|
||||
// New period has not been prepared.
|
||||
playbackInfo =
|
||||
playbackInfo.copyWithTrackInfo(TrackGroupArray.EMPTY, emptyTrackSelectorResult);
|
||||
resetRendererPosition(periodPositionUs);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
||||
@ -48,6 +49,8 @@ import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinit
|
||||
import com.google.android.exoplayer2.testutil.FakeTrackSelection;
|
||||
import com.google.android.exoplayer2.testutil.FakeTrackSelector;
|
||||
import com.google.android.exoplayer2.testutil.RobolectricUtil;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
@ -2288,6 +2291,59 @@ public final class ExoPlayerTest {
|
||||
.isAtLeast(C.usToMs(expectedDurationUs));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTrackSelectorThenSeekToUnpreparedPeriod_returnsEmptyTrackGroups()
|
||||
throws Exception {
|
||||
Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
MediaSource[] fakeMediaSources = {
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||
new FakeMediaSource(fakeTimeline, null, Builder.AUDIO_FORMAT)
|
||||
};
|
||||
MediaSource mediaSource =
|
||||
new ConcatenatingMediaSource(
|
||||
/* isAtomic= */ false,
|
||||
/* useLazyPreparation= */ true,
|
||||
new ShuffleOrder.DefaultShuffleOrder(0),
|
||||
fakeMediaSources);
|
||||
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testSendMessages")
|
||||
.pause()
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
.seek(/* windowIndex= */ 1, /* positionMs= */ 0)
|
||||
.play()
|
||||
.build();
|
||||
List<TrackGroupArray> trackGroupsList = new ArrayList<>();
|
||||
List<TrackSelectionArray> trackSelectionsList = new ArrayList<>();
|
||||
new Builder()
|
||||
.setMediaSource(mediaSource)
|
||||
.setTrackSelector(trackSelector)
|
||||
.setRenderers(renderer)
|
||||
.setActionSchedule(actionSchedule)
|
||||
.setEventListener(
|
||||
new EventListener() {
|
||||
@Override
|
||||
public void onTracksChanged(
|
||||
TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
||||
trackGroupsList.add(trackGroups);
|
||||
trackSelectionsList.add(trackSelections);
|
||||
}
|
||||
})
|
||||
.build(context)
|
||||
.start()
|
||||
.blockUntilEnded(TIMEOUT_MS);
|
||||
assertThat(trackGroupsList).hasSize(3);
|
||||
// First track groups of the 1st period are reported.
|
||||
// Then the seek to an unprepared period will result in empty track groups and selections being
|
||||
// returned.
|
||||
// Then the track groups of the 2nd period are reported.
|
||||
assertThat(trackGroupsList.get(0).get(0).getFormat(0)).isEqualTo(Builder.VIDEO_FORMAT);
|
||||
assertThat(trackGroupsList.get(1)).isEqualTo(TrackGroupArray.EMPTY);
|
||||
assertThat(trackSelectionsList.get(1).get(0)).isNull();
|
||||
assertThat(trackGroupsList.get(2).get(0).getFormat(0)).isEqualTo(Builder.AUDIO_FORMAT);
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private static ActionSchedule.Builder addSurfaceSwitch(ActionSchedule.Builder builder) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user