diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/StreamKey.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/StreamKey.java index 9d51f42979..1caeaca61e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/StreamKey.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/StreamKey.java @@ -19,11 +19,11 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; /** - * Identifies a stream in a {@link FilterableManifest} by the index of the containing period, the - * index of the containing group within the period, and the index of the track within the group. + * A key for a subset of media which can be separately loaded (a "stream"). * - *

Note that the interpretation of period, group and index depends on the type of manifest being - * filtered. + *

The stream key consists of a period index, a group index within the period and a track index + * within the group. The interpretation of these indices depends on the type of media for which the + * stream key is used. */ public final class StreamKey implements Comparable { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java index b7f5a07b60..532131ba7d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java @@ -19,8 +19,11 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.trackselection.TrackSelection; import java.io.IOException; +import java.util.Collections; +import java.util.List; import org.checkerframework.checker.nullness.compatqual.NullableType; /** @@ -83,6 +86,22 @@ public interface MediaPeriod extends SequenceableLoader { */ TrackGroupArray getTrackGroups(); + /** + * Returns a list of {@link StreamKey stream keys} which allow to filter the media in this period + * to load only the parts needed to play the provided {@link TrackSelection}. + * + *

This method is only called after the period has been prepared. + * + * @param trackSelection The {@link TrackSelection} describing the tracks for which stream keys + * are requested. + * @return The corresponding {@link StreamKey stream keys} for the selected tracks, or an empty + * list if filtering is not possible and the entire media needs to be loaded to play the + * selected tracks. + */ + default List getStreamKeys(TrackSelection trackSelection) { + return Collections.emptyList(); + } + /** * Performs a track selection. * diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java index 14b54bc471..fc22c45c5a 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java @@ -20,6 +20,7 @@ import android.util.Base64; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox; +import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; @@ -37,12 +38,11 @@ import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.TransferListener; import java.io.IOException; import java.util.ArrayList; +import java.util.List; -/** - * A SmoothStreaming {@link MediaPeriod}. - */ -/* package */ final class SsMediaPeriod implements MediaPeriod, - SequenceableLoader.Callback> { +/** A SmoothStreaming {@link MediaPeriod}. */ +/* package */ final class SsMediaPeriod + implements MediaPeriod, SequenceableLoader.Callback> { private static final int INITIALIZATION_VECTOR_SIZE = 8; @@ -112,6 +112,8 @@ import java.util.ArrayList; eventDispatcher.mediaPeriodReleased(); } + // MediaPeriod implementation. + @Override public void prepare(Callback callback, long positionUs) { this.callback = callback; @@ -157,6 +159,16 @@ import java.util.ArrayList; return positionUs; } + @Override + public List getStreamKeys(TrackSelection trackSelection) { + List streamKeys = new ArrayList<>(trackSelection.length()); + int streamElementIndex = trackGroups.indexOf(trackSelection.getTrackGroup()); + for (int i = 0; i < trackSelection.length(); i++) { + streamKeys.add(new StreamKey(streamElementIndex, trackSelection.getIndexInTrackGroup(i))); + } + return streamKeys; + } + @Override public void discardBuffer(long positionUs, boolean toKeyframe) { for (ChunkSampleStream sampleStream : sampleStreams) { @@ -211,7 +223,7 @@ import java.util.ArrayList; return positionUs; } - // SequenceableLoader.Callback implementation + // SequenceableLoader.Callback implementation. @Override public void onContinueLoadingRequested(ChunkSampleStream sampleStream) { @@ -277,5 +289,4 @@ import java.util.ArrayList; data[firstPosition] = data[secondPosition]; data[secondPosition] = temp; } - }