Use TrackKey in place of RepresentetionKey, StreamKey, RenditionKey

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=199767518
This commit is contained in:
eguven 2018-06-08 02:11:37 -07:00 committed by Oliver Woodman
parent 8e65696f02
commit a406dc8bee
31 changed files with 255 additions and 400 deletions

View File

@ -37,6 +37,7 @@ import com.google.android.exoplayer2.offline.DownloadManager.TaskState;
import com.google.android.exoplayer2.offline.DownloadService; import com.google.android.exoplayer2.offline.DownloadService;
import com.google.android.exoplayer2.offline.ProgressiveDownloadHelper; import com.google.android.exoplayer2.offline.ProgressiveDownloadHelper;
import com.google.android.exoplayer2.offline.SegmentDownloadAction; import com.google.android.exoplayer2.offline.SegmentDownloadAction;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.offline.TrackKey; import com.google.android.exoplayer2.offline.TrackKey;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
@ -111,7 +112,7 @@ public class DownloadTracker implements DownloadManager.Listener {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <K> List<K> getOfflineStreamKeys(Uri uri) { public List<StreamKey> getOfflineStreamKeys(Uri uri) {
if (!trackedDownloadStates.containsKey(uri)) { if (!trackedDownloadStates.containsKey(uri)) {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -282,6 +283,7 @@ public class DownloadTracker implements DownloadManager.Listener {
Toast.makeText( Toast.makeText(
context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG) context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG)
.show(); .show();
Log.e(TAG, "Failed to start download", e);
} }
@Override @Override

View File

@ -49,6 +49,7 @@ import com.google.android.exoplayer2.drm.UnsupportedDrmException;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException; import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.offline.FilteringManifestParser; import com.google.android.exoplayer2.offline.FilteringManifestParser;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.BehindLiveWindowException; import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource; import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource; import com.google.android.exoplayer2.source.ExtractorMediaSource;
@ -59,14 +60,11 @@ import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource; import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser; import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource; import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.StreamKey;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
@ -446,22 +444,19 @@ public class PlayerActivity extends Activity
new DefaultDashChunkSource.Factory(mediaDataSourceFactory), new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
buildDataSourceFactory(false)) buildDataSourceFactory(false))
.setManifestParser( .setManifestParser(
new FilteringManifestParser<>( new FilteringManifestParser<>(new DashManifestParser(), getOfflineStreamKeys(uri)))
new DashManifestParser(), (List<RepresentationKey>) getOfflineStreamKeys(uri)))
.createMediaSource(uri); .createMediaSource(uri);
case C.TYPE_SS: case C.TYPE_SS:
return new SsMediaSource.Factory( return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory), new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
buildDataSourceFactory(false)) buildDataSourceFactory(false))
.setManifestParser( .setManifestParser(
new FilteringManifestParser<>( new FilteringManifestParser<>(new SsManifestParser(), getOfflineStreamKeys(uri)))
new SsManifestParser(), (List<StreamKey>) getOfflineStreamKeys(uri)))
.createMediaSource(uri); .createMediaSource(uri);
case C.TYPE_HLS: case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory) return new HlsMediaSource.Factory(mediaDataSourceFactory)
.setPlaylistParser( .setPlaylistParser(
new FilteringManifestParser<>( new FilteringManifestParser<>(new HlsPlaylistParser(), getOfflineStreamKeys(uri)))
new HlsPlaylistParser(), (List<RenditionKey>) getOfflineStreamKeys(uri)))
.createMediaSource(uri); .createMediaSource(uri);
case C.TYPE_OTHER: case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri); return new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
@ -471,7 +466,7 @@ public class PlayerActivity extends Activity
} }
} }
private List<?> getOfflineStreamKeys(Uri uri) { private List<StreamKey> getOfflineStreamKeys(Uri uri) {
return ((DemoApplication) getApplication()).getDownloadTracker().getOfflineStreamKeys(uri); return ((DemoApplication) getApplication()).getDownloadTracker().getOfflineStreamKeys(uri);
} }

View File

@ -22,9 +22,8 @@ import java.util.List;
* keys. * keys.
* *
* @param <T> The manifest type. * @param <T> The manifest type.
* @param <K> The stream key type.
*/ */
public interface FilterableManifest<T, K> { public interface FilterableManifest<T> {
/** /**
* Returns a copy of the manifest including only the streams specified by the given keys. If the * Returns a copy of the manifest including only the streams specified by the given keys. If the
@ -33,5 +32,5 @@ public interface FilterableManifest<T, K> {
* @param streamKeys A non-empty list of stream keys. * @param streamKeys A non-empty list of stream keys.
* @return The filtered manifest. * @return The filtered manifest.
*/ */
T copy(List<K> streamKeys); T copy(List<StreamKey> streamKeys);
} }

View File

@ -21,25 +21,24 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
/** A manifest parser that includes only the tracks identified by the given track keys. */ /** A manifest parser that includes only the streams identified by the given stream keys. */
public final class FilteringManifestParser<T extends FilterableManifest<T, K>, K> public final class FilteringManifestParser<T extends FilterableManifest<T>> implements Parser<T> {
implements Parser<T> {
private final Parser<T> parser; private final Parser<T> parser;
private final List<K> trackKeys; private final List<StreamKey> streamKeys;
/** /**
* @param parser A parser for the manifest that will be filtered. * @param parser A parser for the manifest that will be filtered.
* @param trackKeys The track keys. If null or empty then filtering will not occur. * @param streamKeys The stream keys. If null or empty then filtering will not occur.
*/ */
public FilteringManifestParser(Parser<T> parser, List<K> trackKeys) { public FilteringManifestParser(Parser<T> parser, List<StreamKey> streamKeys) {
this.parser = parser; this.parser = parser;
this.trackKeys = trackKeys; this.streamKeys = streamKeys;
} }
@Override @Override
public T parse(Uri uri, InputStream inputStream) throws IOException { public T parse(Uri uri, InputStream inputStream) throws IOException {
T manifest = parser.parse(uri, inputStream); T manifest = parser.parse(uri, inputStream);
return trackKeys == null || trackKeys.isEmpty() ? manifest : manifest.copy(trackKeys); return streamKeys == null || streamKeys.isEmpty() ? manifest : manifest.copy(streamKeys);
} }
} }

View File

@ -25,19 +25,11 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
/** /** {@link DownloadAction} for {@link SegmentDownloader}s. */
* {@link DownloadAction} for {@link SegmentDownloader}s. public abstract class SegmentDownloadAction extends DownloadAction {
*
* @param <K> The type of the representation key object.
*/
public abstract class SegmentDownloadAction<K extends Comparable<K>> extends DownloadAction {
/** /** Base class for {@link SegmentDownloadAction} {@link Deserializer}s. */
* Base class for {@link SegmentDownloadAction} {@link Deserializer}s. protected abstract static class SegmentDownloadActionDeserializer extends Deserializer {
*
* @param <K> The type of the representation key object.
*/
protected abstract static class SegmentDownloadActionDeserializer<K> extends Deserializer {
public SegmentDownloadActionDeserializer(String type, int version) { public SegmentDownloadActionDeserializer(String type, int version) {
super(type, version); super(type, version);
@ -52,7 +44,7 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
byte[] data = new byte[dataLength]; byte[] data = new byte[dataLength];
input.readFully(data); input.readFully(data);
int keyCount = input.readInt(); int keyCount = input.readInt();
List<K> keys = new ArrayList<>(); List<StreamKey> keys = new ArrayList<>();
for (int i = 0; i < keyCount; i++) { for (int i = 0; i < keyCount; i++) {
keys.add(readKey(input)); keys.add(readKey(input));
} }
@ -60,14 +52,14 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
} }
/** Deserializes a key from the {@code input}. */ /** Deserializes a key from the {@code input}. */
protected abstract K readKey(DataInputStream input) throws IOException; protected abstract StreamKey readKey(DataInputStream input) throws IOException;
/** Returns a {@link DownloadAction}. */ /** Returns a {@link DownloadAction}. */
protected abstract DownloadAction createDownloadAction( protected abstract DownloadAction createDownloadAction(
Uri manifestUri, boolean isRemoveAction, byte[] data, List<K> keys); Uri manifestUri, boolean isRemoveAction, byte[] data, List<StreamKey> keys);
} }
public final List<K> keys; public final List<StreamKey> keys;
/** /**
* @param type The type of the action. * @param type The type of the action.
@ -84,13 +76,13 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
Uri uri, Uri uri,
boolean isRemoveAction, boolean isRemoveAction,
@Nullable byte[] data, @Nullable byte[] data,
List<K> keys) { List<StreamKey> keys) {
super(type, version, uri, isRemoveAction, data); super(type, version, uri, isRemoveAction, data);
if (isRemoveAction) { if (isRemoveAction) {
Assertions.checkArgument(keys.isEmpty()); Assertions.checkArgument(keys.isEmpty());
this.keys = Collections.emptyList(); this.keys = Collections.emptyList();
} else { } else {
ArrayList<K> mutableKeys = new ArrayList<>(keys); ArrayList<StreamKey> mutableKeys = new ArrayList<>(keys);
Collections.sort(mutableKeys); Collections.sort(mutableKeys);
this.keys = Collections.unmodifiableList(mutableKeys); this.keys = Collections.unmodifiableList(mutableKeys);
} }
@ -109,7 +101,7 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
} }
/** Serializes the {@code key} into the {@code output}. */ /** Serializes the {@code key} into the {@code output}. */
protected abstract void writeKey(DataOutputStream output, K key) throws IOException; protected abstract void writeKey(DataOutputStream output, StreamKey key) throws IOException;
@Override @Override
public boolean equals(@Nullable Object o) { public boolean equals(@Nullable Object o) {
@ -119,7 +111,7 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
if (!super.equals(o)) { if (!super.equals(o)) {
return false; return false;
} }
SegmentDownloadAction<?> that = (SegmentDownloadAction<?>) o; SegmentDownloadAction that = (SegmentDownloadAction) o;
return keys.equals(that.keys); return keys.equals(that.keys);
} }

View File

@ -35,10 +35,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Base class for multi segment stream downloaders. * Base class for multi segment stream downloaders.
* *
* @param <M> The type of the manifest object. * @param <M> The type of the manifest object.
* @param <K> The type of the streams key object.
*/ */
public abstract class SegmentDownloader<M extends FilterableManifest<M, K>, K> public abstract class SegmentDownloader<M extends FilterableManifest<M>> implements Downloader {
implements Downloader {
/** Smallest unit of content to be downloaded. */ /** Smallest unit of content to be downloaded. */
protected static class Segment implements Comparable<Segment> { protected static class Segment implements Comparable<Segment> {
@ -68,7 +66,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M, K>, K>
private final Cache cache; private final Cache cache;
private final CacheDataSource dataSource; private final CacheDataSource dataSource;
private final CacheDataSource offlineDataSource; private final CacheDataSource offlineDataSource;
private final ArrayList<K> streamKeys; private final ArrayList<StreamKey> streamKeys;
private final AtomicBoolean isCanceled; private final AtomicBoolean isCanceled;
private volatile int totalSegments; private volatile int totalSegments;
@ -82,7 +80,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M, K>, K>
* @param constructorHelper A {@link DownloaderConstructorHelper} instance. * @param constructorHelper A {@link DownloaderConstructorHelper} instance.
*/ */
public SegmentDownloader( public SegmentDownloader(
Uri manifestUri, List<K> streamKeys, DownloaderConstructorHelper constructorHelper) { Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
this.manifestUri = manifestUri; this.manifestUri = manifestUri;
this.streamKeys = new ArrayList<>(streamKeys); this.streamKeys = new ArrayList<>(streamKeys);
this.cache = constructorHelper.getCache(); this.cache = constructorHelper.getCache();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2017 The Android Open Source Project * Copyright (C) 2018 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -13,25 +13,46 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.smoothstreaming.manifest; package com.google.android.exoplayer2.offline;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
/** Uniquely identifies a track in a {@link SsManifest}. */ /**
* Identifies a given track 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.
*/
public final class StreamKey implements Comparable<StreamKey> { public final class StreamKey implements Comparable<StreamKey> {
public final int streamElementIndex; /** The period index. */
public final int periodIndex;
/** The group index. */
public final int groupIndex;
/** The track index. */
public final int trackIndex; public final int trackIndex;
public StreamKey(int streamElementIndex, int trackIndex) { /**
this.streamElementIndex = streamElementIndex; * @param groupIndex The group index.
* @param trackIndex The track index.
*/
public StreamKey(int groupIndex, int trackIndex) {
this(0, groupIndex, trackIndex);
}
/**
* @param periodIndex The period index.
* @param groupIndex The group index.
* @param trackIndex The track index.
*/
public StreamKey(int periodIndex, int groupIndex, int trackIndex) {
this.periodIndex = periodIndex;
this.groupIndex = groupIndex;
this.trackIndex = trackIndex; this.trackIndex = trackIndex;
} }
@Override @Override
public String toString() { public String toString() {
return streamElementIndex + "." + trackIndex; return periodIndex + "." + groupIndex + "." + trackIndex;
} }
@Override @Override
@ -44,12 +65,15 @@ public final class StreamKey implements Comparable<StreamKey> {
} }
StreamKey that = (StreamKey) o; StreamKey that = (StreamKey) o;
return streamElementIndex == that.streamElementIndex && trackIndex == that.trackIndex; return periodIndex == that.periodIndex
&& groupIndex == that.groupIndex
&& trackIndex == that.trackIndex;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = streamElementIndex; int result = periodIndex;
result = 31 * result + groupIndex;
result = 31 * result + trackIndex; result = 31 * result + trackIndex;
return result; return result;
} }
@ -58,9 +82,12 @@ public final class StreamKey implements Comparable<StreamKey> {
@Override @Override
public int compareTo(@NonNull StreamKey o) { public int compareTo(@NonNull StreamKey o) {
int result = streamElementIndex - o.streamElementIndex; int result = periodIndex - o.periodIndex;
if (result == 0) { if (result == 0) {
result = trackIndex - o.trackIndex; result = groupIndex - o.groupIndex;
if (result == 0) {
result = trackIndex - o.trackIndex;
}
} }
return result; return result;
} }

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.offline.FilterableManifest; import com.google.android.exoplayer2.offline.FilterableManifest;
import com.google.android.exoplayer2.offline.StreamKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
@ -27,7 +28,7 @@ import java.util.List;
* Represents a DASH media presentation description (mpd), as defined by ISO/IEC 23009-1:2014 * Represents a DASH media presentation description (mpd), as defined by ISO/IEC 23009-1:2014
* Section 5.3.1.2. * Section 5.3.1.2.
*/ */
public class DashManifest implements FilterableManifest<DashManifest, RepresentationKey> { public class DashManifest implements FilterableManifest<DashManifest> {
/** /**
* The {@code availabilityStartTime} value in milliseconds since epoch, or {@link C#TIME_UNSET} if * The {@code availabilityStartTime} value in milliseconds since epoch, or {@link C#TIME_UNSET} if
@ -123,10 +124,10 @@ public class DashManifest implements FilterableManifest<DashManifest, Representa
} }
@Override @Override
public final DashManifest copy(List<RepresentationKey> streamKeys) { public final DashManifest copy(List<StreamKey> streamKeys) {
LinkedList<RepresentationKey> keys = new LinkedList<>(streamKeys); LinkedList<StreamKey> keys = new LinkedList<>(streamKeys);
Collections.sort(keys); Collections.sort(keys);
keys.add(new RepresentationKey(-1, -1, -1)); // Add a stopper key to the end keys.add(new StreamKey(-1, -1, -1)); // Add a stopper key to the end
ArrayList<Period> copyPeriods = new ArrayList<>(); ArrayList<Period> copyPeriods = new ArrayList<>();
long shiftMs = 0; long shiftMs = 0;
@ -153,21 +154,21 @@ public class DashManifest implements FilterableManifest<DashManifest, Representa
} }
private static ArrayList<AdaptationSet> copyAdaptationSets( private static ArrayList<AdaptationSet> copyAdaptationSets(
List<AdaptationSet> adaptationSets, LinkedList<RepresentationKey> keys) { List<AdaptationSet> adaptationSets, LinkedList<StreamKey> keys) {
RepresentationKey key = keys.poll(); StreamKey key = keys.poll();
int periodIndex = key.periodIndex; int periodIndex = key.periodIndex;
ArrayList<AdaptationSet> copyAdaptationSets = new ArrayList<>(); ArrayList<AdaptationSet> copyAdaptationSets = new ArrayList<>();
do { do {
int adaptationSetIndex = key.adaptationSetIndex; int adaptationSetIndex = key.groupIndex;
AdaptationSet adaptationSet = adaptationSets.get(adaptationSetIndex); AdaptationSet adaptationSet = adaptationSets.get(adaptationSetIndex);
List<Representation> representations = adaptationSet.representations; List<Representation> representations = adaptationSet.representations;
ArrayList<Representation> copyRepresentations = new ArrayList<>(); ArrayList<Representation> copyRepresentations = new ArrayList<>();
do { do {
Representation representation = representations.get(key.representationIndex); Representation representation = representations.get(key.trackIndex);
copyRepresentations.add(representation); copyRepresentations.add(representation);
key = keys.poll(); key = keys.poll();
} while(key.periodIndex == periodIndex && key.adaptationSetIndex == adaptationSetIndex); } while (key.periodIndex == periodIndex && key.groupIndex == adaptationSetIndex);
copyAdaptationSets.add(new AdaptationSet(adaptationSet.id, adaptationSet.type, copyAdaptationSets.add(new AdaptationSet(adaptationSet.id, adaptationSet.type,
copyRepresentations, adaptationSet.accessibilityDescriptors, copyRepresentations, adaptationSet.accessibilityDescriptors,

View File

@ -1,76 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.dash.manifest;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/** Uniquely identifies a {@link Representation} in a {@link DashManifest}. */
public final class RepresentationKey implements Comparable<RepresentationKey> {
public final int periodIndex;
public final int adaptationSetIndex;
public final int representationIndex;
public RepresentationKey(int periodIndex, int adaptationSetIndex, int representationIndex) {
this.periodIndex = periodIndex;
this.adaptationSetIndex = adaptationSetIndex;
this.representationIndex = representationIndex;
}
@Override
public String toString() {
return periodIndex + "." + adaptationSetIndex + "." + representationIndex;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RepresentationKey that = (RepresentationKey) o;
return periodIndex == that.periodIndex
&& adaptationSetIndex == that.adaptationSetIndex
&& representationIndex == that.representationIndex;
}
@Override
public int hashCode() {
int result = periodIndex;
result = 31 * result + adaptationSetIndex;
result = 31 * result + representationIndex;
return result;
}
// Comparable implementation.
@Override
public int compareTo(@NonNull RepresentationKey o) {
int result = periodIndex - o.periodIndex;
if (result == 0) {
result = adaptationSetIndex - o.adaptationSetIndex;
if (result == 0) {
result = representationIndex - o.representationIndex;
}
}
return result;
}
}

View File

@ -20,29 +20,32 @@ import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadAction; import com.google.android.exoplayer2.offline.DownloadAction;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloadAction; import com.google.android.exoplayer2.offline.SegmentDownloadAction;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey; import com.google.android.exoplayer2.offline.StreamKey;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
/** An action to download or remove downloaded DASH streams. */ /** An action to download or remove downloaded DASH streams. */
public final class DashDownloadAction extends SegmentDownloadAction<RepresentationKey> { public final class DashDownloadAction extends SegmentDownloadAction {
private static final String TYPE = "dash"; private static final String TYPE = "dash";
private static final int VERSION = 0; private static final int VERSION = 0;
public static final Deserializer DESERIALIZER = public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<RepresentationKey>(TYPE, VERSION) { new SegmentDownloadActionDeserializer(TYPE, VERSION) {
@Override @Override
protected RepresentationKey readKey(DataInputStream input) throws IOException { protected StreamKey readKey(DataInputStream input) throws IOException {
return new RepresentationKey(input.readInt(), input.readInt(), input.readInt()); int periodIndex = input.readInt();
int groupIndex = input.readInt();
int trackIndex = input.readInt();
return new StreamKey(periodIndex, groupIndex, trackIndex);
} }
@Override @Override
protected DownloadAction createDownloadAction( protected DownloadAction createDownloadAction(
Uri uri, boolean isRemoveAction, byte[] data, List<RepresentationKey> keys) { Uri uri, boolean isRemoveAction, byte[] data, List<StreamKey> keys) {
return new DashDownloadAction(uri, isRemoveAction, data, keys); return new DashDownloadAction(uri, isRemoveAction, data, keys);
} }
}; };
@ -55,7 +58,7 @@ public final class DashDownloadAction extends SegmentDownloadAction<Representati
* downloaded. If {@code removeAction} is true, {@code keys} must be empty. * downloaded. If {@code removeAction} is true, {@code keys} must be empty.
*/ */
public DashDownloadAction( public DashDownloadAction(
Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<RepresentationKey> keys) { Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<StreamKey> keys) {
super(TYPE, VERSION, uri, isRemoveAction, data, keys); super(TYPE, VERSION, uri, isRemoveAction, data, keys);
} }
@ -65,10 +68,10 @@ public final class DashDownloadAction extends SegmentDownloadAction<Representati
} }
@Override @Override
protected void writeKey(DataOutputStream output, RepresentationKey key) throws IOException { protected void writeKey(DataOutputStream output, StreamKey key) throws IOException {
output.writeInt(key.periodIndex); output.writeInt(key.periodIndex);
output.writeInt(key.adaptationSetIndex); output.writeInt(key.groupIndex);
output.writeInt(key.representationIndex); output.writeInt(key.trackIndex);
} }
} }

View File

@ -19,6 +19,7 @@ import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.offline.DownloadHelper; import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.offline.TrackKey; import com.google.android.exoplayer2.offline.TrackKey;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
@ -26,7 +27,6 @@ import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser; import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser;
import com.google.android.exoplayer2.source.dash.manifest.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -51,9 +51,8 @@ public final class DashDownloadHelper extends DownloadHelper {
@Override @Override
protected void prepareInternal() throws IOException { protected void prepareInternal() throws IOException {
manifest = DataSource dataSource = manifestDataSourceFactory.createDataSource();
ParsingLoadable.load( manifest = ParsingLoadable.load(dataSource, new DashManifestParser(), uri);
manifestDataSourceFactory.createDataSource(), new DashManifestParser(), uri);
} }
/** Returns the DASH manifest. Must not be called until after preparation completes. */ /** Returns the DASH manifest. Must not be called until after preparation completes. */
@ -87,23 +86,20 @@ public final class DashDownloadHelper extends DownloadHelper {
@Override @Override
public DashDownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys) { public DashDownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys) {
return new DashDownloadAction( return new DashDownloadAction(uri, /* isRemoveAction= */ false, data, toStreamKeys(trackKeys));
uri, /* isRemoveAction= */ false, data, toRepresentationKeys(trackKeys));
} }
@Override @Override
public DashDownloadAction getRemoveAction(@Nullable byte[] data) { public DashDownloadAction getRemoveAction(@Nullable byte[] data) {
return new DashDownloadAction( return new DashDownloadAction(uri, /* isRemoveAction= */ true, data, Collections.emptyList());
uri, /* isRemoveAction= */ true, data, Collections.<RepresentationKey>emptyList());
} }
private static List<RepresentationKey> toRepresentationKeys(List<TrackKey> trackKeys) { private static List<StreamKey> toStreamKeys(List<TrackKey> trackKeys) {
List<RepresentationKey> representationKeys = new ArrayList<>(trackKeys.size()); List<StreamKey> streamKeys = new ArrayList<>(trackKeys.size());
for (int i = 0; i < trackKeys.size(); i++) { for (int i = 0; i < trackKeys.size(); i++) {
TrackKey trackKey = trackKeys.get(i); TrackKey trackKey = trackKeys.get(i);
representationKeys.add( streamKeys.add(new StreamKey(trackKey.periodIndex, trackKey.groupIndex, trackKey.trackIndex));
new RepresentationKey(trackKey.periodIndex, trackKey.groupIndex, trackKey.trackIndex));
} }
return representationKeys; return streamKeys;
} }
} }

View File

@ -22,6 +22,7 @@ import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.offline.DownloadException; import com.google.android.exoplayer2.offline.DownloadException;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex; import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
import com.google.android.exoplayer2.source.dash.DashUtil; import com.google.android.exoplayer2.source.dash.DashUtil;
import com.google.android.exoplayer2.source.dash.DashWrappingSegmentIndex; import com.google.android.exoplayer2.source.dash.DashWrappingSegmentIndex;
@ -30,7 +31,6 @@ import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.Period; import com.google.android.exoplayer2.source.dash.manifest.Period;
import com.google.android.exoplayer2.source.dash.manifest.RangedUri; import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
import com.google.android.exoplayer2.source.dash.manifest.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import java.io.IOException; import java.io.IOException;
@ -51,9 +51,7 @@ import java.util.List;
* // period. * // period.
* DashDownloader dashDownloader = * DashDownloader dashDownloader =
* new DashDownloader( * new DashDownloader(
* manifestUrl, * manifestUrl, Collections.singletonList(new StreamKey(0, 0, 0)), constructorHelper);
* Collections.singletonList(new RepresentationKey(0, 0, 0)),
* constructorHelper);
* // Perform the download. * // Perform the download.
* dashDownloader.download(); * dashDownloader.download();
* // Access downloaded data using CacheDataSource * // Access downloaded data using CacheDataSource
@ -61,19 +59,17 @@ import java.util.List;
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE); * new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
* }</pre> * }</pre>
*/ */
public final class DashDownloader extends SegmentDownloader<DashManifest, RepresentationKey> { public final class DashDownloader extends SegmentDownloader<DashManifest> {
/** /**
* @param manifestUri The {@link Uri} of the manifest to be downloaded. * @param manifestUri The {@link Uri} of the manifest to be downloaded.
* @param representationKeys Keys defining which representations in the manifest should be * @param streamKeys Keys defining which representations in the manifest should be selected for
* selected for download. If empty, all representations are downloaded. * download. If empty, all representations are downloaded.
* @param constructorHelper A {@link DownloaderConstructorHelper} instance. * @param constructorHelper A {@link DownloaderConstructorHelper} instance.
*/ */
public DashDownloader( public DashDownloader(
Uri manifestUri, Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
List<RepresentationKey> representationKeys, super(manifestUri, streamKeys, constructorHelper);
DownloaderConstructorHelper constructorHelper) {
super(manifestUri, representationKeys, constructorHelper);
} }
@Override @Override

View File

@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -58,17 +59,17 @@ public class DashManifestTest {
newAdaptationSet(8, representations[2][0]), newAdaptationSet(8, representations[2][0]),
newAdaptationSet(9, representations[2][1]))); newAdaptationSet(9, representations[2][1])));
List<RepresentationKey> keys = List<StreamKey> keys =
Arrays.asList( Arrays.asList(
new RepresentationKey(0, 0, 0), new StreamKey(0, 0, 0),
new RepresentationKey(0, 0, 1), new StreamKey(0, 0, 1),
new RepresentationKey(0, 1, 2), new StreamKey(0, 1, 2),
new RepresentationKey(1, 0, 1), new StreamKey(1, 0, 1),
new RepresentationKey(1, 1, 0), new StreamKey(1, 1, 0),
new RepresentationKey(1, 1, 2), new StreamKey(1, 1, 2),
new RepresentationKey(2, 0, 1), new StreamKey(2, 0, 1),
new RepresentationKey(2, 0, 2), new StreamKey(2, 0, 2),
new RepresentationKey(2, 1, 0)); new StreamKey(2, 1, 0));
// Keys don't need to be in any particular order // Keys don't need to be in any particular order
Collections.shuffle(keys, new Random(0)); Collections.shuffle(keys, new Random(0));
@ -105,8 +106,7 @@ public class DashManifestTest {
newPeriod("4", 4, newAdaptationSet(5, representations[1][0]))); newPeriod("4", 4, newAdaptationSet(5, representations[1][0])));
DashManifest copyManifest = DashManifest copyManifest =
sourceManifest.copy( sourceManifest.copy(Arrays.asList(new StreamKey(0, 0, 0), new StreamKey(1, 0, 0)));
Arrays.asList(new RepresentationKey(0, 0, 0), new RepresentationKey(1, 0, 0)));
DashManifest expectedManifest = DashManifest expectedManifest =
newDashManifest( newDashManifest(
@ -141,12 +141,12 @@ public class DashManifestTest {
DashManifest copyManifest = DashManifest copyManifest =
sourceManifest.copy( sourceManifest.copy(
Arrays.asList( Arrays.asList(
new RepresentationKey(0, 0, 0), new StreamKey(0, 0, 0),
new RepresentationKey(0, 0, 1), new StreamKey(0, 0, 1),
new RepresentationKey(0, 1, 2), new StreamKey(0, 1, 2),
new RepresentationKey(2, 0, 1), new StreamKey(2, 0, 1),
new RepresentationKey(2, 0, 2), new StreamKey(2, 0, 2),
new RepresentationKey(2, 1, 0))); new StreamKey(2, 1, 0)));
DashManifest expectedManifest = DashManifest expectedManifest =
newDashManifest( newDashManifest(

View File

@ -21,7 +21,7 @@ import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadAction; import com.google.android.exoplayer2.offline.DownloadAction;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.upstream.DummyDataSource; import com.google.android.exoplayer2.upstream.DummyDataSource;
import com.google.android.exoplayer2.upstream.cache.Cache; import com.google.android.exoplayer2.upstream.cache.Cache;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -104,16 +104,13 @@ public class DashDownloadActionTest {
DashDownloadAction action6 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null); DashDownloadAction action6 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
DashDownloadAction action7 = DashDownloadAction action7 =
newAction( newAction(uri1, /* isRemoveAction= */ false, /* data= */ null, new StreamKey(0, 0, 0));
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(0, 0, 0));
assertNotEqual(action6, action7); assertNotEqual(action6, action7);
DashDownloadAction action8 = DashDownloadAction action8 =
newAction( newAction(uri1, /* isRemoveAction= */ false, /* data= */ null, new StreamKey(1, 1, 1));
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(1, 1, 1));
DashDownloadAction action9 = DashDownloadAction action9 =
newAction( newAction(uri1, /* isRemoveAction= */ false, /* data= */ null, new StreamKey(0, 0, 0));
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(0, 0, 0));
assertNotEqual(action8, action9); assertNotEqual(action8, action9);
DashDownloadAction action10 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null); DashDownloadAction action10 = newAction(uri1, /* isRemoveAction= */ true, /* data= */ null);
@ -125,27 +122,26 @@ public class DashDownloadActionTest {
uri1, uri1,
/* isRemoveAction= */ false, /* isRemoveAction= */ false,
/* data= */ null, /* data= */ null,
new RepresentationKey(0, 0, 0), new StreamKey(0, 0, 0),
new RepresentationKey(1, 1, 1)); new StreamKey(1, 1, 1));
DashDownloadAction action13 = DashDownloadAction action13 =
newAction( newAction(
uri1, uri1,
/* isRemoveAction= */ false, /* isRemoveAction= */ false,
/* data= */ null, /* data= */ null,
new RepresentationKey(1, 1, 1), new StreamKey(1, 1, 1),
new RepresentationKey(0, 0, 0)); new StreamKey(0, 0, 0));
assertEqual(action12, action13); assertEqual(action12, action13);
DashDownloadAction action14 = DashDownloadAction action14 =
newAction( newAction(uri1, /* isRemoveAction= */ false, /* data= */ null, new StreamKey(0, 0, 0));
uri1, /* isRemoveAction= */ false, /* data= */ null, new RepresentationKey(0, 0, 0));
DashDownloadAction action15 = DashDownloadAction action15 =
newAction( newAction(
uri1, uri1,
/* isRemoveAction= */ false, /* isRemoveAction= */ false,
/* data= */ null, /* data= */ null,
new RepresentationKey(1, 1, 1), new StreamKey(1, 1, 1),
new RepresentationKey(0, 0, 0)); new StreamKey(0, 0, 0));
assertNotEqual(action14, action15); assertNotEqual(action14, action15);
DashDownloadAction action16 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null); DashDownloadAction action16 = newAction(uri1, /* isRemoveAction= */ false, /* data= */ null);
@ -168,8 +164,8 @@ public class DashDownloadActionTest {
uri2, uri2,
/* isRemoveAction= */ false, /* isRemoveAction= */ false,
/* data= */ null, /* data= */ null,
new RepresentationKey(0, 0, 0), new StreamKey(0, 0, 0),
new RepresentationKey(1, 1, 1))); new StreamKey(1, 1, 1)));
} }
private static void assertNotEqual(DashDownloadAction action1, DashDownloadAction action2) { private static void assertNotEqual(DashDownloadAction action1, DashDownloadAction action2) {
@ -197,8 +193,8 @@ public class DashDownloadActionTest {
} }
private static DashDownloadAction newAction( private static DashDownloadAction newAction(
Uri uri, boolean isRemoveAction, @Nullable byte[] data, RepresentationKey... keys) { Uri uri, boolean isRemoveAction, @Nullable byte[] data, StreamKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>(); ArrayList<StreamKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys); Collections.addAll(keysList, keys);
return new DashDownloadAction(uri, isRemoveAction, data, keysList); return new DashDownloadAction(uri, isRemoveAction, data, keysList);
} }

View File

@ -27,7 +27,7 @@ import static org.mockito.Mockito.when;
import com.google.android.exoplayer2.offline.DownloadException; import com.google.android.exoplayer2.offline.DownloadException;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.testutil.FakeDataSource.Factory; import com.google.android.exoplayer2.testutil.FakeDataSource.Factory;
@ -77,7 +77,7 @@ public class DashDownloaderTest {
.setRandomData("audio_segment_2", 5) .setRandomData("audio_segment_2", 5)
.setRandomData("audio_segment_3", 6); .setRandomData("audio_segment_3", 6);
DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new RepresentationKey(0, 0, 0)); DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0));
dashDownloader.download(); dashDownloader.download();
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@ -96,7 +96,7 @@ public class DashDownloaderTest {
.setRandomData("audio_segment_2", 5) .setRandomData("audio_segment_2", 5)
.setRandomData("audio_segment_3", 6); .setRandomData("audio_segment_3", 6);
DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new RepresentationKey(0, 0, 0)); DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0));
dashDownloader.download(); dashDownloader.download();
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@ -115,8 +115,7 @@ public class DashDownloaderTest {
.setRandomData("text_segment_3", 3); .setRandomData("text_segment_3", 3);
DashDownloader dashDownloader = DashDownloader dashDownloader =
getDashDownloader( getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0), new StreamKey(0, 1, 0));
fakeDataSet, new RepresentationKey(0, 0, 0), new RepresentationKey(0, 1, 0));
dashDownloader.download(); dashDownloader.download();
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@ -159,7 +158,7 @@ public class DashDownloaderTest {
when(factory.createDataSource()).thenReturn(fakeDataSource); when(factory.createDataSource()).thenReturn(fakeDataSource);
DashDownloader dashDownloader = DashDownloader dashDownloader =
getDashDownloader(factory, new RepresentationKey(0, 0, 0), new RepresentationKey(0, 1, 0)); getDashDownloader(factory, new StreamKey(0, 0, 0), new StreamKey(0, 1, 0));
dashDownloader.download(); dashDownloader.download();
DataSpec[] openedDataSpecs = fakeDataSource.getAndClearOpenedDataSpecs(); DataSpec[] openedDataSpecs = fakeDataSource.getAndClearOpenedDataSpecs();
@ -191,7 +190,7 @@ public class DashDownloaderTest {
when(factory.createDataSource()).thenReturn(fakeDataSource); when(factory.createDataSource()).thenReturn(fakeDataSource);
DashDownloader dashDownloader = DashDownloader dashDownloader =
getDashDownloader(factory, new RepresentationKey(0, 0, 0), new RepresentationKey(1, 0, 0)); getDashDownloader(factory, new StreamKey(0, 0, 0), new StreamKey(1, 0, 0));
dashDownloader.download(); dashDownloader.download();
DataSpec[] openedDataSpecs = fakeDataSource.getAndClearOpenedDataSpecs(); DataSpec[] openedDataSpecs = fakeDataSource.getAndClearOpenedDataSpecs();
@ -220,7 +219,7 @@ public class DashDownloaderTest {
.endData() .endData()
.setRandomData("audio_segment_3", 6); .setRandomData("audio_segment_3", 6);
DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new RepresentationKey(0, 0, 0)); DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0));
try { try {
dashDownloader.download(); dashDownloader.download();
fail(); fail();
@ -245,7 +244,7 @@ public class DashDownloaderTest {
.endData() .endData()
.setRandomData("audio_segment_3", 6); .setRandomData("audio_segment_3", 6);
DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new RepresentationKey(0, 0, 0)); DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0));
assertThat(dashDownloader.getDownloadedBytes()).isEqualTo(0); assertThat(dashDownloader.getDownloadedBytes()).isEqualTo(0);
try { try {
@ -274,8 +273,7 @@ public class DashDownloaderTest {
.setRandomData("text_segment_3", 3); .setRandomData("text_segment_3", 3);
DashDownloader dashDownloader = DashDownloader dashDownloader =
getDashDownloader( getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0), new StreamKey(0, 1, 0));
fakeDataSet, new RepresentationKey(0, 0, 0), new RepresentationKey(0, 1, 0));
dashDownloader.download(); dashDownloader.download();
dashDownloader.remove(); dashDownloader.remove();
assertCacheEmpty(cache); assertCacheEmpty(cache);
@ -288,7 +286,7 @@ public class DashDownloaderTest {
.setData(TEST_MPD_URI, TEST_MPD_NO_INDEX) .setData(TEST_MPD_URI, TEST_MPD_NO_INDEX)
.setRandomData("test_segment_1", 4); .setRandomData("test_segment_1", 4);
DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new RepresentationKey(0, 0, 0)); DashDownloader dashDownloader = getDashDownloader(fakeDataSet, new StreamKey(0, 0, 0));
try { try {
dashDownloader.download(); dashDownloader.download();
fail(); fail();
@ -299,17 +297,17 @@ public class DashDownloaderTest {
assertCacheEmpty(cache); assertCacheEmpty(cache);
} }
private DashDownloader getDashDownloader(FakeDataSet fakeDataSet, RepresentationKey... keys) { private DashDownloader getDashDownloader(FakeDataSet fakeDataSet, StreamKey... keys) {
return getDashDownloader(new Factory(null).setFakeDataSet(fakeDataSet), keys); return getDashDownloader(new Factory(null).setFakeDataSet(fakeDataSet), keys);
} }
private DashDownloader getDashDownloader(Factory factory, RepresentationKey... keys) { private DashDownloader getDashDownloader(Factory factory, StreamKey... keys) {
return new DashDownloader( return new DashDownloader(
TEST_MPD_URI, keysList(keys), new DownloaderConstructorHelper(cache, factory)); TEST_MPD_URI, keysList(keys), new DownloaderConstructorHelper(cache, factory));
} }
private static ArrayList<RepresentationKey> keysList(RepresentationKey... keys) { private static ArrayList<StreamKey> keysList(StreamKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>(); ArrayList<StreamKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys); Collections.addAll(keysList, keys);
return keysList; return keysList;
} }

View File

@ -27,7 +27,7 @@ import android.os.ConditionVariable;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadManager; import com.google.android.exoplayer2.offline.DownloadManager;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.testutil.DummyMainThread; import com.google.android.exoplayer2.testutil.DummyMainThread;
import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
@ -62,8 +62,8 @@ public class DownloadManagerDashTest {
private File tempFolder; private File tempFolder;
private FakeDataSet fakeDataSet; private FakeDataSet fakeDataSet;
private DownloadManager downloadManager; private DownloadManager downloadManager;
private RepresentationKey fakeRepresentationKey1; private StreamKey fakeStreamKey1;
private RepresentationKey fakeRepresentationKey2; private StreamKey fakeStreamKey2;
private TestDownloadManagerListener downloadManagerListener; private TestDownloadManagerListener downloadManagerListener;
private File actionFile; private File actionFile;
private DummyMainThread dummyMainThread; private DummyMainThread dummyMainThread;
@ -88,8 +88,8 @@ public class DownloadManagerDashTest {
.setRandomData("text_segment_2", 2) .setRandomData("text_segment_2", 2)
.setRandomData("text_segment_3", 3); .setRandomData("text_segment_3", 3);
fakeRepresentationKey1 = new RepresentationKey(0, 0, 0); fakeStreamKey1 = new StreamKey(0, 0, 0);
fakeRepresentationKey2 = new RepresentationKey(0, 1, 0); fakeStreamKey2 = new StreamKey(0, 1, 0);
actionFile = new File(tempFolder, "actionFile"); actionFile = new File(tempFolder, "actionFile");
createDownloadManager(); createDownloadManager();
} }
@ -133,7 +133,7 @@ public class DownloadManagerDashTest {
@Override @Override
public void run() { public void run() {
// Setup an Action and immediately release the DM. // Setup an Action and immediately release the DM.
handleDownloadAction(fakeRepresentationKey1, fakeRepresentationKey2); handleDownloadAction(fakeStreamKey1, fakeStreamKey2);
downloadManager.release(); downloadManager.release();
} }
}); });
@ -160,15 +160,15 @@ public class DownloadManagerDashTest {
@Test @Test
public void testHandleDownloadAction() throws Throwable { public void testHandleDownloadAction() throws Throwable {
handleDownloadAction(fakeRepresentationKey1, fakeRepresentationKey2); handleDownloadAction(fakeStreamKey1, fakeStreamKey2);
blockUntilTasksCompleteAndThrowAnyDownloadError(); blockUntilTasksCompleteAndThrowAnyDownloadError();
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test @Test
public void testHandleMultipleDownloadAction() throws Throwable { public void testHandleMultipleDownloadAction() throws Throwable {
handleDownloadAction(fakeRepresentationKey1); handleDownloadAction(fakeStreamKey1);
handleDownloadAction(fakeRepresentationKey2); handleDownloadAction(fakeStreamKey2);
blockUntilTasksCompleteAndThrowAnyDownloadError(); blockUntilTasksCompleteAndThrowAnyDownloadError();
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@ -181,13 +181,13 @@ public class DownloadManagerDashTest {
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
handleDownloadAction(fakeRepresentationKey2); handleDownloadAction(fakeStreamKey2);
} }
}) })
.appendReadData(TestUtil.buildTestData(5)) .appendReadData(TestUtil.buildTestData(5))
.endData(); .endData();
handleDownloadAction(fakeRepresentationKey1); handleDownloadAction(fakeStreamKey1);
blockUntilTasksCompleteAndThrowAnyDownloadError(); blockUntilTasksCompleteAndThrowAnyDownloadError();
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
@ -195,7 +195,7 @@ public class DownloadManagerDashTest {
@Test @Test
public void testHandleRemoveAction() throws Throwable { public void testHandleRemoveAction() throws Throwable {
handleDownloadAction(fakeRepresentationKey1); handleDownloadAction(fakeStreamKey1);
blockUntilTasksCompleteAndThrowAnyDownloadError(); blockUntilTasksCompleteAndThrowAnyDownloadError();
@ -210,7 +210,7 @@ public class DownloadManagerDashTest {
@Ignore @Ignore
@Test @Test
public void testHandleRemoveActionBeforeDownloadFinish() throws Throwable { public void testHandleRemoveActionBeforeDownloadFinish() throws Throwable {
handleDownloadAction(fakeRepresentationKey1); handleDownloadAction(fakeStreamKey1);
handleRemoveAction(); handleRemoveAction();
blockUntilTasksCompleteAndThrowAnyDownloadError(); blockUntilTasksCompleteAndThrowAnyDownloadError();
@ -233,7 +233,7 @@ public class DownloadManagerDashTest {
.appendReadData(TestUtil.buildTestData(5)) .appendReadData(TestUtil.buildTestData(5))
.endData(); .endData();
handleDownloadAction(fakeRepresentationKey1); handleDownloadAction(fakeStreamKey1);
assertThat(downloadInProgressCondition.block(ASSERT_TRUE_TIMEOUT)).isTrue(); assertThat(downloadInProgressCondition.block(ASSERT_TRUE_TIMEOUT)).isTrue();
@ -248,7 +248,7 @@ public class DownloadManagerDashTest {
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError(); downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
} }
private void handleDownloadAction(RepresentationKey... keys) { private void handleDownloadAction(StreamKey... keys) {
downloadManager.handleAction(newAction(TEST_MPD_URI, false, null, keys)); downloadManager.handleAction(newAction(TEST_MPD_URI, false, null, keys));
} }
@ -280,8 +280,8 @@ public class DownloadManagerDashTest {
} }
private static DashDownloadAction newAction( private static DashDownloadAction newAction(
Uri uri, boolean isRemoveAction, @Nullable byte[] data, RepresentationKey... keys) { Uri uri, boolean isRemoveAction, @Nullable byte[] data, StreamKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>(); ArrayList<StreamKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys); Collections.addAll(keysList, keys);
return new DashDownloadAction(uri, isRemoveAction, data, keysList); return new DashDownloadAction(uri, isRemoveAction, data, keysList);
} }

View File

@ -29,9 +29,9 @@ import com.google.android.exoplayer2.offline.DownloadManager;
import com.google.android.exoplayer2.offline.DownloadManager.TaskState; import com.google.android.exoplayer2.offline.DownloadManager.TaskState;
import com.google.android.exoplayer2.offline.DownloadService; import com.google.android.exoplayer2.offline.DownloadService;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.scheduler.Requirements; import com.google.android.exoplayer2.scheduler.Requirements;
import com.google.android.exoplayer2.scheduler.Scheduler; import com.google.android.exoplayer2.scheduler.Scheduler;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
import com.google.android.exoplayer2.testutil.DummyMainThread; import com.google.android.exoplayer2.testutil.DummyMainThread;
import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
@ -65,8 +65,8 @@ public class DownloadServiceDashTest {
private SimpleCache cache; private SimpleCache cache;
private File tempFolder; private File tempFolder;
private FakeDataSet fakeDataSet; private FakeDataSet fakeDataSet;
private RepresentationKey fakeRepresentationKey1; private StreamKey fakeStreamKey1;
private RepresentationKey fakeRepresentationKey2; private StreamKey fakeStreamKey2;
private Context context; private Context context;
private DownloadService dashDownloadService; private DownloadService dashDownloadService;
private ConditionVariable pauseDownloadCondition; private ConditionVariable pauseDownloadCondition;
@ -108,8 +108,8 @@ public class DownloadServiceDashTest {
.setRandomData("text_segment_3", 3); .setRandomData("text_segment_3", 3);
final DataSource.Factory fakeDataSourceFactory = final DataSource.Factory fakeDataSourceFactory =
new FakeDataSource.Factory(null).setFakeDataSet(fakeDataSet); new FakeDataSource.Factory(null).setFakeDataSet(fakeDataSet);
fakeRepresentationKey1 = new RepresentationKey(0, 0, 0); fakeStreamKey1 = new StreamKey(0, 0, 0);
fakeRepresentationKey2 = new RepresentationKey(0, 1, 0); fakeStreamKey2 = new StreamKey(0, 1, 0);
dummyMainThread.runOnMainThread( dummyMainThread.runOnMainThread(
new Runnable() { new Runnable() {
@ -180,8 +180,8 @@ public class DownloadServiceDashTest {
@Ignore // b/78877092 @Ignore // b/78877092
@Test @Test
public void testMultipleDownloadAction() throws Throwable { public void testMultipleDownloadAction() throws Throwable {
downloadKeys(fakeRepresentationKey1); downloadKeys(fakeStreamKey1);
downloadKeys(fakeRepresentationKey2); downloadKeys(fakeStreamKey2);
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError(); downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
@ -191,7 +191,7 @@ public class DownloadServiceDashTest {
@Ignore // b/78877092 @Ignore // b/78877092
@Test @Test
public void testRemoveAction() throws Throwable { public void testRemoveAction() throws Throwable {
downloadKeys(fakeRepresentationKey1, fakeRepresentationKey2); downloadKeys(fakeStreamKey1, fakeStreamKey2);
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError(); downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
@ -206,7 +206,7 @@ public class DownloadServiceDashTest {
@Test @Test
public void testRemoveBeforeDownloadComplete() throws Throwable { public void testRemoveBeforeDownloadComplete() throws Throwable {
pauseDownloadCondition = new ConditionVariable(); pauseDownloadCondition = new ConditionVariable();
downloadKeys(fakeRepresentationKey1, fakeRepresentationKey2); downloadKeys(fakeStreamKey1, fakeStreamKey2);
removeAll(); removeAll();
@ -219,7 +219,7 @@ public class DownloadServiceDashTest {
callDownloadServiceOnStart(newAction(TEST_MPD_URI, true, null)); callDownloadServiceOnStart(newAction(TEST_MPD_URI, true, null));
} }
private void downloadKeys(RepresentationKey... keys) { private void downloadKeys(StreamKey... keys) {
callDownloadServiceOnStart(newAction(TEST_MPD_URI, false, null, keys)); callDownloadServiceOnStart(newAction(TEST_MPD_URI, false, null, keys));
} }
@ -236,8 +236,8 @@ public class DownloadServiceDashTest {
} }
private static DashDownloadAction newAction( private static DashDownloadAction newAction(
Uri uri, boolean isRemoveAction, @Nullable byte[] data, RepresentationKey... keys) { Uri uri, boolean isRemoveAction, @Nullable byte[] data, StreamKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>(); ArrayList<StreamKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys); Collections.addAll(keysList, keys);
return new DashDownloadAction(uri, isRemoveAction, data, keysList); return new DashDownloadAction(uri, isRemoveAction, data, keysList);
} }

View File

@ -20,31 +20,31 @@ import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadAction; import com.google.android.exoplayer2.offline.DownloadAction;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloadAction; import com.google.android.exoplayer2.offline.SegmentDownloadAction;
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey; import com.google.android.exoplayer2.offline.StreamKey;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
/** An action to download or remove downloaded HLS streams. */ /** An action to download or remove downloaded HLS streams. */
public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey> { public final class HlsDownloadAction extends SegmentDownloadAction {
private static final String TYPE = "hls"; private static final String TYPE = "hls";
private static final int VERSION = 0; private static final int VERSION = 0;
public static final Deserializer DESERIALIZER = public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<RenditionKey>(TYPE, VERSION) { new SegmentDownloadActionDeserializer(TYPE, VERSION) {
@Override @Override
protected RenditionKey readKey(DataInputStream input) throws IOException { protected StreamKey readKey(DataInputStream input) throws IOException {
int renditionGroup = input.readInt(); int renditionGroup = input.readInt();
int trackIndex = input.readInt(); int trackIndex = input.readInt();
return new RenditionKey(renditionGroup, trackIndex); return new StreamKey(renditionGroup, trackIndex);
} }
@Override @Override
protected DownloadAction createDownloadAction( protected DownloadAction createDownloadAction(
Uri uri, boolean isRemoveAction, byte[] data, List<RenditionKey> keys) { Uri uri, boolean isRemoveAction, byte[] data, List<StreamKey> keys) {
return new HlsDownloadAction(uri, isRemoveAction, data, keys); return new HlsDownloadAction(uri, isRemoveAction, data, keys);
} }
}; };
@ -57,7 +57,7 @@ public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey>
* {@code removeAction} is true, {@code keys} must empty. * {@code removeAction} is true, {@code keys} must empty.
*/ */
public HlsDownloadAction( public HlsDownloadAction(
Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<RenditionKey> keys) { Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<StreamKey> keys) {
super(TYPE, VERSION, uri, isRemoveAction, data, keys); super(TYPE, VERSION, uri, isRemoveAction, data, keys);
} }
@ -67,8 +67,8 @@ public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey>
} }
@Override @Override
protected void writeKey(DataOutputStream output, RenditionKey key) throws IOException { protected void writeKey(DataOutputStream output, StreamKey key) throws IOException {
output.writeInt(key.type); output.writeInt(key.groupIndex);
output.writeInt(key.trackIndex); output.writeInt(key.trackIndex);
} }

View File

@ -19,6 +19,7 @@ import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.offline.DownloadHelper; import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.offline.TrackKey; import com.google.android.exoplayer2.offline.TrackKey;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
@ -26,7 +27,6 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -44,7 +44,7 @@ public final class HlsDownloadHelper extends DownloadHelper {
private final DataSource.Factory manifestDataSourceFactory; private final DataSource.Factory manifestDataSourceFactory;
private @MonotonicNonNull HlsPlaylist playlist; private @MonotonicNonNull HlsPlaylist playlist;
private int[] renditionTypes; private int[] renditionGroups;
public HlsDownloadHelper(Uri uri, DataSource.Factory manifestDataSourceFactory) { public HlsDownloadHelper(Uri uri, DataSource.Factory manifestDataSourceFactory) {
this.uri = uri; this.uri = uri;
@ -78,18 +78,18 @@ public final class HlsDownloadHelper extends DownloadHelper {
// TODO: Generate track groups as in playback. Reverse the mapping in getDownloadAction. // TODO: Generate track groups as in playback. Reverse the mapping in getDownloadAction.
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist; HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
TrackGroup[] trackGroups = new TrackGroup[3]; TrackGroup[] trackGroups = new TrackGroup[3];
renditionTypes = new int[3]; renditionGroups = new int[3];
int trackGroupIndex = 0; int trackGroupIndex = 0;
if (!masterPlaylist.variants.isEmpty()) { if (!masterPlaylist.variants.isEmpty()) {
renditionTypes[trackGroupIndex] = RenditionKey.TYPE_VARIANT; renditionGroups[trackGroupIndex] = HlsMasterPlaylist.GROUP_INDEX_VARIANT;
trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.variants)); trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.variants));
} }
if (!masterPlaylist.audios.isEmpty()) { if (!masterPlaylist.audios.isEmpty()) {
renditionTypes[trackGroupIndex] = RenditionKey.TYPE_AUDIO; renditionGroups[trackGroupIndex] = HlsMasterPlaylist.GROUP_INDEX_AUDIO;
trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.audios)); trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.audios));
} }
if (!masterPlaylist.subtitles.isEmpty()) { if (!masterPlaylist.subtitles.isEmpty()) {
renditionTypes[trackGroupIndex] = RenditionKey.TYPE_SUBTITLE; renditionGroups[trackGroupIndex] = HlsMasterPlaylist.GROUP_INDEX_SUBTITLE;
trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.subtitles)); trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.subtitles));
} }
return new TrackGroupArray(Arrays.copyOf(trackGroups, trackGroupIndex)); return new TrackGroupArray(Arrays.copyOf(trackGroups, trackGroupIndex));
@ -97,15 +97,14 @@ public final class HlsDownloadHelper extends DownloadHelper {
@Override @Override
public HlsDownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys) { public HlsDownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys) {
Assertions.checkNotNull(renditionTypes); Assertions.checkNotNull(renditionGroups);
return new HlsDownloadAction( return new HlsDownloadAction(
uri, /* isRemoveAction= */ false, data, toRenditionKeys(trackKeys, renditionTypes)); uri, /* isRemoveAction= */ false, data, toStreamKeys(trackKeys, renditionGroups));
} }
@Override @Override
public HlsDownloadAction getRemoveAction(@Nullable byte[] data) { public HlsDownloadAction getRemoveAction(@Nullable byte[] data) {
return new HlsDownloadAction( return new HlsDownloadAction(uri, /* isRemoveAction= */ true, data, Collections.emptyList());
uri, /* isRemoveAction= */ true, data, Collections.<RenditionKey>emptyList());
} }
private static Format[] toFormats(List<HlsMasterPlaylist.HlsUrl> hlsUrls) { private static Format[] toFormats(List<HlsMasterPlaylist.HlsUrl> hlsUrls) {
@ -116,11 +115,11 @@ public final class HlsDownloadHelper extends DownloadHelper {
return formats; return formats;
} }
private static List<RenditionKey> toRenditionKeys(List<TrackKey> trackKeys, int[] groups) { private static List<StreamKey> toStreamKeys(List<TrackKey> trackKeys, int[] groups) {
List<RenditionKey> representationKeys = new ArrayList<>(trackKeys.size()); List<StreamKey> representationKeys = new ArrayList<>(trackKeys.size());
for (int i = 0; i < trackKeys.size(); i++) { for (int i = 0; i < trackKeys.size(); i++) {
TrackKey trackKey = trackKeys.get(i); TrackKey trackKey = trackKeys.get(i);
representationKeys.add(new RenditionKey(groups[trackKey.groupIndex], trackKey.trackIndex)); representationKeys.add(new StreamKey(groups[trackKey.groupIndex], trackKey.trackIndex));
} }
return representationKeys; return representationKeys;
} }

View File

@ -19,12 +19,12 @@ import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
@ -48,7 +48,7 @@ import java.util.List;
* HlsDownloader hlsDownloader = * HlsDownloader hlsDownloader =
* new HlsDownloader( * new HlsDownloader(
* playlistUri, * playlistUri,
* Collections.singletonList(new RenditionKey(RenditionKey.TYPE_VARIANT, 0)), * Collections.singletonList(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0)),
* constructorHelper); * constructorHelper);
* // Perform the download. * // Perform the download.
* hlsDownloader.download(); * hlsDownloader.download();
@ -57,19 +57,17 @@ import java.util.List;
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE); * new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
* }</pre> * }</pre>
*/ */
public final class HlsDownloader extends SegmentDownloader<HlsPlaylist, RenditionKey> { public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
/** /**
* @param playlistUri The {@link Uri} of the playlist to be downloaded. * @param playlistUri The {@link Uri} of the playlist to be downloaded.
* @param renditionKeys Keys defining which renditions in the playlist should be selected for * @param streamKeys Keys defining which renditions in the playlist should be selected for
* download. If empty, all renditions are downloaded. * download. If empty, all renditions are downloaded.
* @param constructorHelper A {@link DownloaderConstructorHelper} instance. * @param constructorHelper A {@link DownloaderConstructorHelper} instance.
*/ */
public HlsDownloader( public HlsDownloader(
Uri playlistUri, Uri playlistUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
List<RenditionKey> renditionKeys, super(playlistUri, streamKeys, constructorHelper);
DownloaderConstructorHelper constructorHelper) {
super(playlistUri, renditionKeys, constructorHelper);
} }
@Override @Override

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.hls.playlist; package com.google.android.exoplayer2.source.hls.playlist;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -24,6 +25,10 @@ import java.util.List;
/** Represents an HLS master playlist. */ /** Represents an HLS master playlist. */
public final class HlsMasterPlaylist extends HlsPlaylist { public final class HlsMasterPlaylist extends HlsPlaylist {
public static final int GROUP_INDEX_VARIANT = 0;
public static final int GROUP_INDEX_AUDIO = 1;
public static final int GROUP_INDEX_SUBTITLE = 2;
/** /**
* Represents a url in an HLS master playlist. * Represents a url in an HLS master playlist.
*/ */
@ -108,13 +113,13 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
} }
@Override @Override
public HlsMasterPlaylist copy(List<RenditionKey> renditionKeys) { public HlsMasterPlaylist copy(List<StreamKey> streamKeys) {
return new HlsMasterPlaylist( return new HlsMasterPlaylist(
baseUri, baseUri,
tags, tags,
copyRenditionsList(variants, RenditionKey.TYPE_VARIANT, renditionKeys), copyRenditionsList(variants, GROUP_INDEX_VARIANT, streamKeys),
copyRenditionsList(audios, RenditionKey.TYPE_AUDIO, renditionKeys), copyRenditionsList(audios, GROUP_INDEX_AUDIO, streamKeys),
copyRenditionsList(subtitles, RenditionKey.TYPE_SUBTITLE, renditionKeys), copyRenditionsList(subtitles, GROUP_INDEX_SUBTITLE, streamKeys),
muxedAudioFormat, muxedAudioFormat,
muxedCaptionFormats); muxedCaptionFormats);
} }
@ -133,13 +138,13 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
} }
private static List<HlsUrl> copyRenditionsList( private static List<HlsUrl> copyRenditionsList(
List<HlsUrl> renditions, int renditionType, List<RenditionKey> renditionKeys) { List<HlsUrl> renditions, int groupIndex, List<StreamKey> streamKeys) {
List<HlsUrl> copiedRenditions = new ArrayList<>(renditionKeys.size()); List<HlsUrl> copiedRenditions = new ArrayList<>(streamKeys.size());
for (int i = 0; i < renditions.size(); i++) { for (int i = 0; i < renditions.size(); i++) {
HlsUrl rendition = renditions.get(i); HlsUrl rendition = renditions.get(i);
for (int j = 0; j < renditionKeys.size(); j++) { for (int j = 0; j < streamKeys.size(); j++) {
RenditionKey renditionKey = renditionKeys.get(j); StreamKey streamKey = streamKeys.get(j);
if (renditionKey.type == renditionType && renditionKey.trackIndex == i) { if (streamKey.groupIndex == groupIndex && streamKey.trackIndex == i) {
copiedRenditions.add(rendition); copiedRenditions.add(rendition);
break; break;
} }

View File

@ -20,6 +20,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.offline.StreamKey;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Collections; import java.util.Collections;
@ -256,7 +257,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
} }
@Override @Override
public HlsMediaPlaylist copy(List<RenditionKey> renditionKeys) { public HlsMediaPlaylist copy(List<StreamKey> streamKeys) {
return this; return this;
} }

View File

@ -20,7 +20,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
/** Represents an HLS playlist. */ /** Represents an HLS playlist. */
public abstract class HlsPlaylist implements FilterableManifest<HlsPlaylist, RenditionKey> { public abstract class HlsPlaylist implements FilterableManifest<HlsPlaylist> {
/** /**
* The base uri. Used to resolve relative paths. * The base uri. Used to resolve relative paths.

View File

@ -1,79 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.hls.playlist;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** Uniquely identifies a rendition in an {@link HlsMasterPlaylist}. */
public final class RenditionKey implements Comparable<RenditionKey> {
/** Types of rendition. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_VARIANT, TYPE_AUDIO, TYPE_SUBTITLE})
public @interface Type {}
public static final int TYPE_VARIANT = 0;
public static final int TYPE_AUDIO = 1;
public static final int TYPE_SUBTITLE = 2;
public final @Type int type;
public final int trackIndex;
public RenditionKey(@Type int type, int trackIndex) {
this.type = type;
this.trackIndex = trackIndex;
}
@Override
public String toString() {
return type + "." + trackIndex;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RenditionKey that = (RenditionKey) o;
return type == that.type && trackIndex == that.trackIndex;
}
@Override
public int hashCode() {
int result = type;
result = 31 * result + trackIndex;
return result;
}
// Comparable implementation.
@Override
public int compareTo(@NonNull RenditionKey other) {
int result = type - other.type;
if (result == 0) {
result = trackIndex - other.trackIndex;
}
return result;
}
}

View File

@ -36,7 +36,8 @@ import static com.google.common.truth.Truth.assertThat;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSource.Factory; import com.google.android.exoplayer2.testutil.FakeDataSource.Factory;
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
@ -181,17 +182,18 @@ public class HlsDownloaderTest {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
private HlsDownloader getHlsDownloader(String mediaPlaylistUri, List<RenditionKey> keys) { private HlsDownloader getHlsDownloader(String mediaPlaylistUri, List<StreamKey> keys) {
Factory factory = new Factory(null).setFakeDataSet(fakeDataSet); Factory factory = new Factory(null).setFakeDataSet(fakeDataSet);
return new HlsDownloader( return new HlsDownloader(
Uri.parse(mediaPlaylistUri), keys, new DownloaderConstructorHelper(cache, factory)); Uri.parse(mediaPlaylistUri), keys, new DownloaderConstructorHelper(cache, factory));
} }
private static ArrayList<RenditionKey> getKeys(int... variantIndices) { private static ArrayList<StreamKey> getKeys(int... variantIndices) {
ArrayList<RenditionKey> renditionKeys = new ArrayList<>(); ArrayList<StreamKey> streamKeys = new ArrayList<>();
for (int variantIndex : variantIndices) { for (int variantIndex : variantIndices) {
renditionKeys.add(new RenditionKey(RenditionKey.TYPE_VARIANT, variantIndex)); final int trackIndex = variantIndex;
streamKeys.add(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, trackIndex));
} }
return renditionKeys; return streamKeys;
} }
} }

View File

@ -19,6 +19,7 @@ import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.offline.FilterableManifest; import com.google.android.exoplayer2.offline.FilterableManifest;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.UriUtil; import com.google.android.exoplayer2.util.UriUtil;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
@ -33,7 +34,7 @@ import java.util.UUID;
* @see <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">IIS Smooth * @see <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">IIS Smooth
* Streaming Client Manifest Format</a> * Streaming Client Manifest Format</a>
*/ */
public class SsManifest implements FilterableManifest<SsManifest, StreamKey> { public class SsManifest implements FilterableManifest<SsManifest> {
public static final int UNSET_LOOKAHEAD = -1; public static final int UNSET_LOOKAHEAD = -1;
@ -130,7 +131,7 @@ public class SsManifest implements FilterableManifest<SsManifest, StreamKey> {
List<Format> copiedFormats = new ArrayList<>(); List<Format> copiedFormats = new ArrayList<>();
for (int i = 0; i < sortedKeys.size(); i++) { for (int i = 0; i < sortedKeys.size(); i++) {
StreamKey key = sortedKeys.get(i); StreamKey key = sortedKeys.get(i);
StreamElement streamElement = streamElements[key.streamElementIndex]; StreamElement streamElement = streamElements[key.groupIndex];
if (streamElement != currentStreamElement && currentStreamElement != null) { if (streamElement != currentStreamElement && currentStreamElement != null) {
// We're advancing to a new stream element. Add the current one. // We're advancing to a new stream element. Add the current one.
copiedStreamElements.add(currentStreamElement.copy(copiedFormats.toArray(new Format[0]))); copiedStreamElements.add(currentStreamElement.copy(copiedFormats.toArray(new Format[0])));

View File

@ -20,24 +20,26 @@ import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadAction; import com.google.android.exoplayer2.offline.DownloadAction;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloadAction; import com.google.android.exoplayer2.offline.SegmentDownloadAction;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
/** An action to download or remove downloaded SmoothStreaming streams. */ /** An action to download or remove downloaded SmoothStreaming streams. */
public final class SsDownloadAction extends SegmentDownloadAction<StreamKey> { public final class SsDownloadAction extends SegmentDownloadAction {
private static final String TYPE = "ss"; private static final String TYPE = "ss";
private static final int VERSION = 0; private static final int VERSION = 0;
public static final Deserializer DESERIALIZER = public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<StreamKey>(TYPE, VERSION) { new SegmentDownloadActionDeserializer(TYPE, VERSION) {
@Override @Override
protected StreamKey readKey(DataInputStream input) throws IOException { protected StreamKey readKey(DataInputStream input) throws IOException {
return new StreamKey(input.readInt(), input.readInt()); int groupIndex = input.readInt();
int trackIndex = input.readInt();
return new StreamKey(groupIndex, trackIndex);
} }
@Override @Override
@ -66,7 +68,7 @@ public final class SsDownloadAction extends SegmentDownloadAction<StreamKey> {
@Override @Override
protected void writeKey(DataOutputStream output, StreamKey key) throws IOException { protected void writeKey(DataOutputStream output, StreamKey key) throws IOException {
output.writeInt(key.streamElementIndex); output.writeInt(key.groupIndex);
output.writeInt(key.trackIndex); output.writeInt(key.trackIndex);
} }

View File

@ -18,12 +18,12 @@ package com.google.android.exoplayer2.source.smoothstreaming.offline;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadHelper; import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.offline.TrackKey; import com.google.android.exoplayer2.offline.TrackKey;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.StreamKey;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -82,8 +82,7 @@ public final class SsDownloadHelper extends DownloadHelper {
@Override @Override
public SsDownloadAction getRemoveAction(@Nullable byte[] data) { public SsDownloadAction getRemoveAction(@Nullable byte[] data) {
return new SsDownloadAction( return new SsDownloadAction(uri, /* isRemoveAction= */ true, data, Collections.emptyList());
uri, /* isRemoveAction= */ true, data, Collections.<StreamKey>emptyList());
} }
private static List<StreamKey> toStreamKeys(List<TrackKey> trackKeys) { private static List<StreamKey> toStreamKeys(List<TrackKey> trackKeys) {

View File

@ -19,11 +19,11 @@ import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.StreamKey;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
@ -54,7 +54,7 @@ import java.util.List;
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE); * new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
* }</pre> * }</pre>
*/ */
public final class SsDownloader extends SegmentDownloader<SsManifest, StreamKey> { public final class SsDownloader extends SegmentDownloader<SsManifest> {
/** /**
* @param manifestUri The {@link Uri} of the manifest to be downloaded. * @param manifestUri The {@link Uri} of the manifest to be downloaded.

View File

@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.ProtectionElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.ProtectionElement;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;

View File

@ -20,11 +20,11 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.net.Uri; import android.net.Uri;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.dash.DashUtil; import com.google.android.exoplayer2.source.dash.DashUtil;
import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet; import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
import com.google.android.exoplayer2.source.dash.offline.DashDownloader; import com.google.android.exoplayer2.source.dash.offline.DashDownloader;
import com.google.android.exoplayer2.testutil.HostActivity; import com.google.android.exoplayer2.testutil.HostActivity;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
@ -106,7 +106,7 @@ public final class DashDownloadTest extends ActivityInstrumentationTestCase2<Hos
private DashDownloader downloadContent() throws Exception { private DashDownloader downloadContent() throws Exception {
DashManifest dashManifest = DashManifest dashManifest =
DashUtil.loadManifest(httpDataSourceFactory.createDataSource(), MANIFEST_URI); DashUtil.loadManifest(httpDataSourceFactory.createDataSource(), MANIFEST_URI);
ArrayList<RepresentationKey> keys = new ArrayList<>(); ArrayList<StreamKey> keys = new ArrayList<>();
for (int pIndex = 0; pIndex < dashManifest.getPeriodCount(); pIndex++) { for (int pIndex = 0; pIndex < dashManifest.getPeriodCount(); pIndex++) {
List<AdaptationSet> adaptationSets = dashManifest.getPeriod(pIndex).adaptationSets; List<AdaptationSet> adaptationSets = dashManifest.getPeriod(pIndex).adaptationSets;
for (int aIndex = 0; aIndex < adaptationSets.size(); aIndex++) { for (int aIndex = 0; aIndex < adaptationSets.size(); aIndex++) {
@ -116,7 +116,7 @@ public final class DashDownloadTest extends ActivityInstrumentationTestCase2<Hos
String id = representations.get(rIndex).format.id; String id = representations.get(rIndex).format.id;
if (DashTestData.AAC_AUDIO_REPRESENTATION_ID.equals(id) if (DashTestData.AAC_AUDIO_REPRESENTATION_ID.equals(id)
|| DashTestData.H264_CDD_FIXED.equals(id)) { || DashTestData.H264_CDD_FIXED.equals(id)) {
keys.add(new RepresentationKey(pIndex, aIndex, rIndex)); keys.add(new StreamKey(pIndex, aIndex, rIndex));
} }
} }
} }