Search in sources :

Example 16 with StreamKey

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;
}
Also used : ExoTrackSelection(com.google.android.exoplayer2.trackselection.ExoTrackSelection) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) ArrayList(java.util.ArrayList) HlsMultivariantPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist) StreamKey(com.google.android.exoplayer2.offline.StreamKey)

Example 17 with StreamKey

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();
}
Also used : Context(android.content.Context) DefaultDownloadIndex(com.google.android.exoplayer2.offline.DefaultDownloadIndex) SimpleCache(com.google.android.exoplayer2.upstream.cache.SimpleCache) DummyMainThread(com.google.android.exoplayer2.testutil.DummyMainThread) NoOpCacheEvictor(com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor) FakeDataSet(com.google.android.exoplayer2.testutil.FakeDataSet) File(java.io.File) StreamKey(com.google.android.exoplayer2.offline.StreamKey) Before(org.junit.Before)

Example 18 with StreamKey

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));
}
Also used : DownloadRequest(com.google.android.exoplayer2.offline.DownloadRequest)

Example 19 with StreamKey

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;
}
Also used : ExoTrackSelection(com.google.android.exoplayer2.trackselection.ExoTrackSelection) ArrayList(java.util.ArrayList) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) StreamKey(com.google.android.exoplayer2.offline.StreamKey)

Example 20 with StreamKey

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;
}
Also used : ArrayList(java.util.ArrayList) StreamKey(com.google.android.exoplayer2.offline.StreamKey)

Aggregations

StreamKey (com.google.android.exoplayer2.offline.StreamKey)27 Test (org.junit.Test)18 FakeDataSet (com.google.android.exoplayer2.testutil.FakeDataSet)11 ArrayList (java.util.ArrayList)10 CacheDataSource (com.google.android.exoplayer2.upstream.cache.CacheDataSource)5 DefaultDownloaderFactory (com.google.android.exoplayer2.offline.DefaultDownloaderFactory)4 RequestSet (com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet)4 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)4 Downloader (com.google.android.exoplayer2.offline.Downloader)3 DownloaderFactory (com.google.android.exoplayer2.offline.DownloaderFactory)3 FakeDataSource (com.google.android.exoplayer2.testutil.FakeDataSource)3 Context (android.content.Context)2 Format (com.google.android.exoplayer2.Format)2 DefaultDownloadIndex (com.google.android.exoplayer2.offline.DefaultDownloadIndex)2 DownloadRequest (com.google.android.exoplayer2.offline.DownloadRequest)2 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)2 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)2 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)2 SsTestUtils.createSsManifest (com.google.android.exoplayer2.source.smoothstreaming.SsTestUtils.createSsManifest)2 DummyMainThread (com.google.android.exoplayer2.testutil.DummyMainThread)2