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;
}
-
}