Search in sources :

Example 1 with HlsPlaylist

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

the class HlsMediaPlaylistParserTest method testParseMediaPlaylist.

public void testParseMediaPlaylist() {
    Uri playlistUri = Uri.parse("https://example.com/test.m3u8");
    String playlistString = "#EXTM3U\n" + "#EXT-X-VERSION:3\n" + "#EXT-X-PLAYLIST-TYPE:VOD\n" + "#EXT-X-START:TIME-OFFSET=-25" + "#EXT-X-TARGETDURATION:8\n" + "#EXT-X-MEDIA-SEQUENCE:2679\n" + "#EXT-X-DISCONTINUITY-SEQUENCE:4\n" + "#EXT-X-ALLOW-CACHE:YES\n" + "\n" + "#EXTINF:7.975,\n" + "#EXT-X-BYTERANGE:51370@0\n" + "https://priv.example.com/fileSequence2679.ts\n" + "\n" + "#EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=2680\",IV=0x1566B\n" + "#EXTINF:7.975,\n" + "#EXT-X-BYTERANGE:51501@2147483648\n" + "https://priv.example.com/fileSequence2680.ts\n" + "\n" + "#EXT-X-KEY:METHOD=NONE\n" + "#EXTINF:7.941,\n" + // @2147535149
    "#EXT-X-BYTERANGE:51501\n" + "https://priv.example.com/fileSequence2681.ts\n" + "\n" + "#EXT-X-DISCONTINUITY\n" + "#EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=2682\"\n" + "#EXTINF:7.975,\n" + // @2147586650
    "#EXT-X-BYTERANGE:51740\n" + "https://priv.example.com/fileSequence2682.ts\n" + "\n" + "#EXTINF:7.975,\n" + "https://priv.example.com/fileSequence2683.ts\n" + "#EXT-X-ENDLIST";
    InputStream inputStream = new ByteArrayInputStream(playlistString.getBytes(Charset.forName(C.UTF8_NAME)));
    try {
        HlsPlaylist playlist = new HlsPlaylistParser().parse(playlistUri, inputStream);
        assertNotNull(playlist);
        assertEquals(HlsPlaylist.TYPE_MEDIA, playlist.type);
        HlsMediaPlaylist mediaPlaylist = (HlsMediaPlaylist) playlist;
        assertEquals(HlsMediaPlaylist.PLAYLIST_TYPE_VOD, mediaPlaylist.playlistType);
        assertEquals(mediaPlaylist.durationUs - 25000000, mediaPlaylist.startOffsetUs);
        assertEquals(2679, mediaPlaylist.mediaSequence);
        assertEquals(3, mediaPlaylist.version);
        assertTrue(mediaPlaylist.hasEndTag);
        List<Segment> segments = mediaPlaylist.segments;
        assertNotNull(segments);
        assertEquals(5, segments.size());
        Segment segment = segments.get(0);
        assertEquals(4, mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence);
        assertEquals(7975000, segment.durationUs);
        assertFalse(segment.isEncrypted);
        assertEquals(null, segment.encryptionKeyUri);
        assertEquals(null, segment.encryptionIV);
        assertEquals(51370, segment.byterangeLength);
        assertEquals(0, segment.byterangeOffset);
        assertEquals("https://priv.example.com/fileSequence2679.ts", segment.url);
        segment = segments.get(1);
        assertEquals(0, segment.relativeDiscontinuitySequence);
        assertEquals(7975000, segment.durationUs);
        assertTrue(segment.isEncrypted);
        assertEquals("https://priv.example.com/key.php?r=2680", segment.encryptionKeyUri);
        assertEquals("0x1566B", segment.encryptionIV);
        assertEquals(51501, segment.byterangeLength);
        assertEquals(2147483648L, segment.byterangeOffset);
        assertEquals("https://priv.example.com/fileSequence2680.ts", segment.url);
        segment = segments.get(2);
        assertEquals(0, segment.relativeDiscontinuitySequence);
        assertEquals(7941000, segment.durationUs);
        assertFalse(segment.isEncrypted);
        assertEquals(null, segment.encryptionKeyUri);
        assertEquals(null, segment.encryptionIV);
        assertEquals(51501, segment.byterangeLength);
        assertEquals(2147535149L, segment.byterangeOffset);
        assertEquals("https://priv.example.com/fileSequence2681.ts", segment.url);
        segment = segments.get(3);
        assertEquals(1, segment.relativeDiscontinuitySequence);
        assertEquals(7975000, segment.durationUs);
        assertTrue(segment.isEncrypted);
        assertEquals("https://priv.example.com/key.php?r=2682", segment.encryptionKeyUri);
        // 0xA7A == 2682.
        assertNotNull(segment.encryptionIV);
        assertEquals("A7A", segment.encryptionIV.toUpperCase(Locale.getDefault()));
        assertEquals(51740, segment.byterangeLength);
        assertEquals(2147586650L, segment.byterangeOffset);
        assertEquals("https://priv.example.com/fileSequence2682.ts", segment.url);
        segment = segments.get(4);
        assertEquals(1, segment.relativeDiscontinuitySequence);
        assertEquals(7975000, segment.durationUs);
        assertTrue(segment.isEncrypted);
        assertEquals("https://priv.example.com/key.php?r=2682", segment.encryptionKeyUri);
        // 0xA7B == 2683.
        assertNotNull(segment.encryptionIV);
        assertEquals("A7B", segment.encryptionIV.toUpperCase(Locale.getDefault()));
        assertEquals(C.LENGTH_UNSET, segment.byterangeLength);
        assertEquals(0, segment.byterangeOffset);
        assertEquals("https://priv.example.com/fileSequence2683.ts", segment.url);
    } catch (IOException exception) {
        fail(exception.getMessage());
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) Uri(android.net.Uri) Segment(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment)

Example 2 with HlsPlaylist

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

the class HlsMediaPeriodTest method getSteamKeys_isCompatibleWithHlsMultivariantPlaylistFilter.

@Test
public void getSteamKeys_isCompatibleWithHlsMultivariantPlaylistFilter() {
    HlsMultivariantPlaylist testMultivariantPlaylist = createMultivariantPlaylist(/* variants= */
    Arrays.asList(createAudioOnlyVariant(/* peakBitrate= */
    10000), createMuxedVideoAudioVariant(/* peakBitrate= */
    200000), createAudioOnlyVariant(/* peakBitrate= */
    300000), createMuxedVideoAudioVariant(/* peakBitrate= */
    400000), createMuxedVideoAudioVariant(/* peakBitrate= */
    600000)), /* audios= */
    Arrays.asList(createAudioRendition(/* language= */
    "spa"), createAudioRendition(/* language= */
    "ger"), createAudioRendition(/* language= */
    "tur")), /* subtitles= */
    Arrays.asList(createSubtitleRendition(/* language= */
    "spa"), createSubtitleRendition(/* language= */
    "ger"), createSubtitleRendition(/* language= */
    "tur")), /* muxedAudioFormat= */
    createAudioFormat("eng"), /* muxedCaptionFormats= */
    Arrays.asList(createSubtitleFormat("eng"), createSubtitleFormat("gsw")));
    FilterableManifestMediaPeriodFactory<HlsPlaylist> mediaPeriodFactory = (playlist, periodIndex) -> {
        HlsDataSourceFactory mockDataSourceFactory = mock(HlsDataSourceFactory.class);
        when(mockDataSourceFactory.createDataSource(anyInt())).thenReturn(mock(DataSource.class));
        HlsPlaylistTracker mockPlaylistTracker = mock(HlsPlaylistTracker.class);
        when(mockPlaylistTracker.getMultivariantPlaylist()).thenReturn((HlsMultivariantPlaylist) playlist);
        MediaPeriodId mediaPeriodId = new MediaPeriodId(/* periodUid= */
        new Object());
        return new HlsMediaPeriod(mock(HlsExtractorFactory.class), mockPlaylistTracker, mockDataSourceFactory, mock(TransferListener.class), mock(DrmSessionManager.class), new DrmSessionEventListener.EventDispatcher().withParameters(/* windowIndex= */
        0, mediaPeriodId), mock(LoadErrorHandlingPolicy.class), new MediaSourceEventListener.EventDispatcher().withParameters(/* windowIndex= */
        0, mediaPeriodId, /* mediaTimeOffsetMs= */
        0), mock(Allocator.class), mock(CompositeSequenceableLoaderFactory.class), /* allowChunklessPreparation= */
        true, HlsMediaSource.METADATA_TYPE_ID3, /* useSessionKeys= */
        false, PlayerId.UNSET);
    };
    MediaPeriodAsserts.assertGetStreamKeysAndManifestFilterIntegration(mediaPeriodFactory, testMultivariantPlaylist);
}
Also used : HlsPlaylistTracker(com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) Arrays(java.util.Arrays) Uri(android.net.Uri) RunWith(org.junit.runner.RunWith) CompositeSequenceableLoaderFactory(com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) Rendition(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition) Format(com.google.android.exoplayer2.Format) PlayerId(com.google.android.exoplayer2.analytics.PlayerId) DrmSessionEventListener(com.google.android.exoplayer2.drm.DrmSessionEventListener) MimeTypes(com.google.android.exoplayer2.util.MimeTypes) HlsPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist) Variant(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) MediaSourceEventListener(com.google.android.exoplayer2.source.MediaSourceEventListener) Allocator(com.google.android.exoplayer2.upstream.Allocator) TransferListener(com.google.android.exoplayer2.upstream.TransferListener) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) DataSource(com.google.android.exoplayer2.upstream.DataSource) MediaPeriodAsserts(com.google.android.exoplayer2.testutil.MediaPeriodAsserts) List(java.util.List) HlsMultivariantPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist) LoadErrorHandlingPolicy(com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy) FilterableManifestMediaPeriodFactory(com.google.android.exoplayer2.testutil.MediaPeriodAsserts.FilterableManifestMediaPeriodFactory) DrmSessionManager(com.google.android.exoplayer2.drm.DrmSessionManager) Collections(java.util.Collections) Mockito.mock(org.mockito.Mockito.mock) HlsPlaylistTracker(com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker) DrmSessionEventListener(com.google.android.exoplayer2.drm.DrmSessionEventListener) HlsPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist) MediaSourceEventListener(com.google.android.exoplayer2.source.MediaSourceEventListener) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) HlsMultivariantPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist) Test(org.junit.Test)

Example 3 with HlsPlaylist

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

the class DefaultHlsPlaylistTracker method onLoadCanceled.

@Override
public void onLoadCanceled(ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
    LoadEventInfo loadEventInfo = new LoadEventInfo(loadable.loadTaskId, loadable.dataSpec, loadable.getUri(), loadable.getResponseHeaders(), elapsedRealtimeMs, loadDurationMs, loadable.bytesLoaded());
    loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId);
    eventDispatcher.loadCanceled(loadEventInfo, C.DATA_TYPE_MANIFEST);
}
Also used : LoadEventInfo(com.google.android.exoplayer2.source.LoadEventInfo)

Example 4 with HlsPlaylist

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

the class HlsMediaPlaylistParserTest method parseMediaPlaylist_withByteRanges.

@Test
public void parseMediaPlaylist_withByteRanges() throws Exception {
    Uri playlistUri = Uri.parse("https://example.com/test.m3u8");
    String playlistString = "#EXTM3U\n" + "#EXT-X-VERSION:3\n" + "#EXT-X-TARGETDURATION:5\n" + "\n" + "#EXT-X-BYTERANGE:200@100\n" + "#EXT-X-MAP:URI=\"stream.mp4\"\n" + "#EXTINF:5,\n" + "#EXT-X-BYTERANGE:400\n" + "stream.mp4\n" + "#EXTINF:5,\n" + "#EXT-X-BYTERANGE:500\n" + "stream.mp4\n" + "#EXT-X-DISCONTINUITY\n" + "#EXT-X-MAP:URI=\"init.mp4\"\n" + "#EXTINF:5,\n" + "segment.mp4\n";
    InputStream inputStream = new ByteArrayInputStream(Util.getUtf8Bytes(playlistString));
    HlsPlaylist playlist = new HlsPlaylistParser().parse(playlistUri, inputStream);
    HlsMediaPlaylist mediaPlaylist = (HlsMediaPlaylist) playlist;
    List<Segment> segments = mediaPlaylist.segments;
    assertThat(segments).isNotNull();
    assertThat(segments).hasSize(3);
    Segment segment = segments.get(0);
    assertThat(segment.initializationSegment.byteRangeOffset).isEqualTo(100);
    assertThat(segment.initializationSegment.byteRangeLength).isEqualTo(200);
    assertThat(segment.byteRangeOffset).isEqualTo(300);
    assertThat(segment.byteRangeLength).isEqualTo(400);
    segment = segments.get(1);
    assertThat(segment.byteRangeOffset).isEqualTo(700);
    assertThat(segment.byteRangeLength).isEqualTo(500);
    segment = segments.get(2);
    assertThat(segment.initializationSegment.byteRangeOffset).isEqualTo(0);
    assertThat(segment.initializationSegment.byteRangeLength).isEqualTo(C.LENGTH_UNSET);
    assertThat(segment.byteRangeOffset).isEqualTo(0);
    assertThat(segment.byteRangeLength).isEqualTo(C.LENGTH_UNSET);
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Uri(android.net.Uri) Segment(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment) Test(org.junit.Test)

Example 5 with HlsPlaylist

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

the class HlsDownloader method getSegments.

@Override
protected List<Segment> getSegments(DataSource dataSource, HlsPlaylist playlist, boolean removing) throws IOException, InterruptedException {
    ArrayList<DataSpec> mediaPlaylistDataSpecs = new ArrayList<>();
    if (playlist instanceof HlsMultivariantPlaylist) {
        HlsMultivariantPlaylist multivariantPlaylist = (HlsMultivariantPlaylist) playlist;
        addMediaPlaylistDataSpecs(multivariantPlaylist.mediaPlaylistUrls, mediaPlaylistDataSpecs);
    } else {
        mediaPlaylistDataSpecs.add(SegmentDownloader.getCompressibleDataSpec(Uri.parse(playlist.baseUri)));
    }
    ArrayList<Segment> segments = new ArrayList<>();
    HashSet<Uri> seenEncryptionKeyUris = new HashSet<>();
    for (DataSpec mediaPlaylistDataSpec : mediaPlaylistDataSpecs) {
        segments.add(new Segment(/* startTimeUs= */
        0, mediaPlaylistDataSpec));
        HlsMediaPlaylist mediaPlaylist;
        try {
            mediaPlaylist = (HlsMediaPlaylist) getManifest(dataSource, mediaPlaylistDataSpec, removing);
        } catch (IOException e) {
            if (!removing) {
                throw e;
            }
            // Generating an incomplete segment list is allowed. Advance to the next media playlist.
            continue;
        }
        @Nullable HlsMediaPlaylist.Segment lastInitSegment = null;
        List<HlsMediaPlaylist.Segment> hlsSegments = mediaPlaylist.segments;
        for (int i = 0; i < hlsSegments.size(); i++) {
            HlsMediaPlaylist.Segment segment = hlsSegments.get(i);
            HlsMediaPlaylist.Segment initSegment = segment.initializationSegment;
            if (initSegment != null && initSegment != lastInitSegment) {
                lastInitSegment = initSegment;
                addSegment(mediaPlaylist, initSegment, seenEncryptionKeyUris, segments);
            }
            addSegment(mediaPlaylist, segment, seenEncryptionKeyUris, segments);
        }
    }
    return segments;
}
Also used : ArrayList(java.util.ArrayList) IOException(java.io.IOException) Uri(android.net.Uri) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) HlsMediaPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist) HlsMultivariantPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist) Nullable(androidx.annotation.Nullable) HashSet(java.util.HashSet)

Aggregations

Uri (android.net.Uri)5 LoadEventInfo (com.google.android.exoplayer2.source.LoadEventInfo)4 Segment (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3 InputStream (java.io.InputStream)3 Test (org.junit.Test)3 HlsMultivariantPlaylist (com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist)2 IOException (java.io.IOException)2 Nullable (androidx.annotation.Nullable)1 AndroidJUnit4 (androidx.test.ext.junit.runners.AndroidJUnit4)1 Format (com.google.android.exoplayer2.Format)1 PlayerId (com.google.android.exoplayer2.analytics.PlayerId)1 DrmSessionEventListener (com.google.android.exoplayer2.drm.DrmSessionEventListener)1 DrmSessionManager (com.google.android.exoplayer2.drm.DrmSessionManager)1 CompositeSequenceableLoaderFactory (com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory)1 MediaLoadData (com.google.android.exoplayer2.source.MediaLoadData)1 MediaPeriodId (com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)1 MediaSourceEventListener (com.google.android.exoplayer2.source.MediaSourceEventListener)1 HlsMediaPlaylist (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist)1 Rendition (com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition)1