use of com.google.android.exoplayer2.offline.StreamKey in project ExoPlayer by google.
the class HlsMediaPeriod method getStreamKeys.
// TODO: When the multivariant playlist does not de-duplicate variants by URL and allows
// Renditions with null URLs, this method must be updated to calculate stream keys that are
// compatible with those that may already be persisted for offline.
@Override
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
// See HlsMultivariantPlaylist.copy for interpretation of StreamKeys.
HlsMultivariantPlaylist multivariantPlaylist = Assertions.checkNotNull(playlistTracker.getMultivariantPlaylist());
boolean hasVariants = !multivariantPlaylist.variants.isEmpty();
int audioWrapperOffset = hasVariants ? 1 : 0;
// Subtitle sample stream wrappers are held last.
int subtitleWrapperOffset = sampleStreamWrappers.length - multivariantPlaylist.subtitles.size();
TrackGroupArray mainWrapperTrackGroups;
int mainWrapperPrimaryGroupIndex;
int[] mainWrapperVariantIndices;
if (hasVariants) {
HlsSampleStreamWrapper mainWrapper = sampleStreamWrappers[0];
mainWrapperVariantIndices = manifestUrlIndicesPerWrapper[0];
mainWrapperTrackGroups = mainWrapper.getTrackGroups();
mainWrapperPrimaryGroupIndex = mainWrapper.getPrimaryTrackGroupIndex();
} else {
mainWrapperVariantIndices = new int[0];
mainWrapperTrackGroups = TrackGroupArray.EMPTY;
mainWrapperPrimaryGroupIndex = 0;
}
List<StreamKey> streamKeys = new ArrayList<>();
boolean needsPrimaryTrackGroupSelection = false;
boolean hasPrimaryTrackGroupSelection = false;
for (ExoTrackSelection trackSelection : trackSelections) {
TrackGroup trackSelectionGroup = trackSelection.getTrackGroup();
int mainWrapperTrackGroupIndex = mainWrapperTrackGroups.indexOf(trackSelectionGroup);
if (mainWrapperTrackGroupIndex != C.INDEX_UNSET) {
if (mainWrapperTrackGroupIndex == mainWrapperPrimaryGroupIndex) {
// Primary group in main wrapper.
hasPrimaryTrackGroupSelection = true;
for (int i = 0; i < trackSelection.length(); i++) {
int variantIndex = mainWrapperVariantIndices[trackSelection.getIndexInTrackGroup(i)];
streamKeys.add(new StreamKey(HlsMultivariantPlaylist.GROUP_INDEX_VARIANT, variantIndex));
}
} else {
// Embedded group in main wrapper.
needsPrimaryTrackGroupSelection = true;
}
} else {
// Audio or subtitle group.
for (int i = audioWrapperOffset; i < sampleStreamWrappers.length; i++) {
TrackGroupArray wrapperTrackGroups = sampleStreamWrappers[i].getTrackGroups();
int selectedTrackGroupIndex = wrapperTrackGroups.indexOf(trackSelectionGroup);
if (selectedTrackGroupIndex != C.INDEX_UNSET) {
int groupIndexType = i < subtitleWrapperOffset ? HlsMultivariantPlaylist.GROUP_INDEX_AUDIO : HlsMultivariantPlaylist.GROUP_INDEX_SUBTITLE;
int[] selectedWrapperUrlIndices = manifestUrlIndicesPerWrapper[i];
for (int trackIndex = 0; trackIndex < trackSelection.length(); trackIndex++) {
int renditionIndex = selectedWrapperUrlIndices[trackSelection.getIndexInTrackGroup(trackIndex)];
streamKeys.add(new StreamKey(groupIndexType, renditionIndex));
}
break;
}
}
}
}
if (needsPrimaryTrackGroupSelection && !hasPrimaryTrackGroupSelection) {
// A track selection includes a variant-embedded track, but no variant is added yet. We use
// the valid variant with the lowest bitrate to reduce overhead.
int lowestBitrateIndex = mainWrapperVariantIndices[0];
int lowestBitrate = multivariantPlaylist.variants.get(mainWrapperVariantIndices[0]).format.bitrate;
for (int i = 1; i < mainWrapperVariantIndices.length; i++) {
int variantBitrate = multivariantPlaylist.variants.get(mainWrapperVariantIndices[i]).format.bitrate;
if (variantBitrate < lowestBitrate) {
lowestBitrate = variantBitrate;
lowestBitrateIndex = mainWrapperVariantIndices[i];
}
}
streamKeys.add(new StreamKey(HlsMultivariantPlaylist.GROUP_INDEX_VARIANT, lowestBitrateIndex));
}
return streamKeys;
}
use of com.google.android.exoplayer2.offline.StreamKey in project ExoPlayer by google.
the class DownloadManagerDashTest method setUp.
@Before
public void setUp() throws Exception {
ShadowLog.stream = System.out;
testThread = new DummyMainThread();
Context context = ApplicationProvider.getApplicationContext();
tempFolder = Util.createTempDirectory(context, "ExoPlayerTest");
File cacheFolder = new File(tempFolder, "cache");
cacheFolder.mkdir();
cache = new SimpleCache(cacheFolder, new NoOpCacheEvictor(), TestUtil.getInMemoryDatabaseProvider());
MockitoAnnotations.initMocks(this);
fakeDataSet = new FakeDataSet().setData(TEST_MPD_URI, TEST_MPD).setRandomData("audio_init_data", 10).setRandomData("audio_segment_1", 4).setRandomData("audio_segment_2", 5).setRandomData("audio_segment_3", 6).setRandomData("text_segment_1", 1).setRandomData("text_segment_2", 2).setRandomData("text_segment_3", 3);
fakeStreamKey1 = new StreamKey(0, 0, 0);
fakeStreamKey2 = new StreamKey(0, 1, 0);
downloadIndex = new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider());
createDownloadManager();
}
use of com.google.android.exoplayer2.offline.StreamKey in project ExoPlayer by google.
the class DownloadManagerDashTest method handleDownloadRequest.
private void handleDownloadRequest(StreamKey... keys) {
DownloadRequest request = getDownloadRequest(keys);
runOnMainThread(() -> downloadManager.addDownload(request));
}
use of com.google.android.exoplayer2.offline.StreamKey in project ExoPlayer by google.
the class DashMediaPeriod method getStreamKeys.
@Override
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
List<AdaptationSet> manifestAdaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
List<StreamKey> streamKeys = new ArrayList<>();
for (ExoTrackSelection trackSelection : trackSelections) {
int trackGroupIndex = trackGroups.indexOf(trackSelection.getTrackGroup());
TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex];
if (trackGroupInfo.trackGroupCategory != TrackGroupInfo.CATEGORY_PRIMARY) {
// Ignore non-primary tracks.
continue;
}
int[] adaptationSetIndices = trackGroupInfo.adaptationSetIndices;
int[] trackIndices = new int[trackSelection.length()];
for (int i = 0; i < trackSelection.length(); i++) {
trackIndices[i] = trackSelection.getIndexInTrackGroup(i);
}
Arrays.sort(trackIndices);
int currentAdaptationSetIndex = 0;
int totalTracksInPreviousAdaptationSets = 0;
int tracksInCurrentAdaptationSet = manifestAdaptationSets.get(adaptationSetIndices[0]).representations.size();
for (int trackIndex : trackIndices) {
while (trackIndex >= totalTracksInPreviousAdaptationSets + tracksInCurrentAdaptationSet) {
currentAdaptationSetIndex++;
totalTracksInPreviousAdaptationSets += tracksInCurrentAdaptationSet;
tracksInCurrentAdaptationSet = manifestAdaptationSets.get(adaptationSetIndices[currentAdaptationSetIndex]).representations.size();
}
streamKeys.add(new StreamKey(periodIndex, adaptationSetIndices[currentAdaptationSetIndex], trackIndex - totalTracksInPreviousAdaptationSets));
}
}
return streamKeys;
}
use of com.google.android.exoplayer2.offline.StreamKey in project ExoPlayer by google.
the class DashManifest method copyAdaptationSets.
private static ArrayList<AdaptationSet> copyAdaptationSets(List<AdaptationSet> adaptationSets, LinkedList<StreamKey> keys) {
StreamKey key = keys.poll();
int periodIndex = key.periodIndex;
ArrayList<AdaptationSet> copyAdaptationSets = new ArrayList<>();
do {
int adaptationSetIndex = key.groupIndex;
AdaptationSet adaptationSet = adaptationSets.get(adaptationSetIndex);
List<Representation> representations = adaptationSet.representations;
ArrayList<Representation> copyRepresentations = new ArrayList<>();
do {
Representation representation = representations.get(key.streamIndex);
copyRepresentations.add(representation);
key = keys.poll();
} while (key.periodIndex == periodIndex && key.groupIndex == adaptationSetIndex);
copyAdaptationSets.add(new AdaptationSet(adaptationSet.id, adaptationSet.type, copyRepresentations, adaptationSet.accessibilityDescriptors, adaptationSet.essentialProperties, adaptationSet.supplementalProperties));
} while (key.periodIndex == periodIndex);
// Add back the last key which doesn't belong to the period being processed
keys.addFirst(key);
return copyAdaptationSets;
}
Aggregations