Search in sources :

Example 11 with Variant

use of com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant 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 12 with Variant

use of com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant in project ExoPlayer by google.

the class HlsMultivariantPlaylistParserTest method parseMultivariantPlaylist_withTtmlSubtitle.

@Test
public void parseMultivariantPlaylist_withTtmlSubtitle() throws IOException {
    HlsMultivariantPlaylist playlistWithTtmlSubtitle = parseMultivariantPlaylist(PLAYLIST_URI, PLAYLIST_WITH_TTML_SUBTITLE);
    HlsMultivariantPlaylist.Variant variant = playlistWithTtmlSubtitle.variants.get(0);
    Format firstTextFormat = playlistWithTtmlSubtitle.subtitles.get(0).format;
    assertThat(firstTextFormat.id).isEqualTo("sub1:English");
    assertThat(firstTextFormat.containerMimeType).isEqualTo(MimeTypes.APPLICATION_M3U8);
    assertThat(firstTextFormat.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_TTML);
    assertThat(variant.format.codecs).isEqualTo("stpp.ttml.im1t,mp4a.40.2,avc1.66.30");
}
Also used : Format(com.google.android.exoplayer2.Format) Variant(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant) Test(org.junit.Test)

Example 13 with Variant

use of com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant in project ExoPlayer by google.

the class HlsMultivariantPlaylistParserTest method testIFrameVariant.

@Test
public void testIFrameVariant() throws IOException {
    HlsMultivariantPlaylist playlist = parseMultivariantPlaylist(PLAYLIST_URI, PLAYLIST_WITH_IFRAME_VARIANTS);
    assertThat(playlist.variants).hasSize(5);
    for (int i = 0; i < 4; i++) {
        assertThat(playlist.variants.get(i).format.roleFlags).isEqualTo(0);
    }
    Variant iFramesOnlyVariant = playlist.variants.get(4);
    assertThat(iFramesOnlyVariant.format.bitrate).isEqualTo(1313400);
    assertThat(iFramesOnlyVariant.format.roleFlags & C.ROLE_FLAG_TRICK_PLAY).isEqualTo(C.ROLE_FLAG_TRICK_PLAY);
}
Also used : Variant(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant) Test(org.junit.Test)

Aggregations

Format (com.google.android.exoplayer2.Format)7 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)5 Variant (com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant)5 ArrayList (java.util.ArrayList)4 Uri (android.net.Uri)3 Nullable (androidx.annotation.Nullable)3 Test (org.junit.Test)3 Metadata (com.google.android.exoplayer2.metadata.Metadata)2 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)2 HlsUrl (com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl)2 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)2 Handler (android.os.Handler)1 Nullable (android.support.annotation.Nullable)1 FlingLayout (com.github.chuross.flinglayout.FlingLayout)1 DefaultLoadControl (com.google.android.exoplayer2.DefaultLoadControl)1 DefaultRenderersFactory (com.google.android.exoplayer2.DefaultRenderersFactory)1 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)1 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)1 OkHttpDataSourceFactory (com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory)1 StreamKey (com.google.android.exoplayer2.offline.StreamKey)1