Search in sources :

Example 51 with Segment

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

the class SefSlowMotionFlattenerTest method getCurrentFrameOutputTimeUs_240fps_outputsExpectedTimes.

@Test
public void getCurrentFrameOutputTimeUs_240fps_outputsExpectedTimes() {
    int captureFrameRate = 240;
    int inputMaxLayer = 3;
    int frameCount = 16;
    SlowMotionData.Segment segment1 = new SlowMotionData.Segment(/* startTimeMs= */
    50, /* endTimeMs= */
    150, /* speedDivisor= */
    2);
    SlowMotionData.Segment segment2 = new SlowMotionData.Segment(/* startTimeMs= */
    210, /* endTimeMs= */
    360, /* speedDivisor= */
    8);
    Format format = createSefSlowMotionFormat(captureFrameRate, inputMaxLayer, Arrays.asList(segment1, segment2));
    SefSlowMotionFlattener sefSlowMotionFlattener = new SefSlowMotionFlattener(format);
    List<Long> outputTimesUs = getOutputTimesUs(sefSlowMotionFlattener, LAYER_SEQUENCE_MAX_LAYER_THREE, frameCount);
    // Test frame inside segment.
    assertThat(outputTimesUs.get(9)).isEqualTo(Math.round((300.0 + 100 + (300 - 210) * 7) * 1000 * 30 / 240));
    // Test frame outside segment.
    assertThat(outputTimesUs.get(13)).isEqualTo(Math.round((433 + 1 / 3.0 + 100 + 150 * 7) * 1000 * 30 / 240));
}
Also used : Format(com.google.android.exoplayer2.Format) SlowMotionData(com.google.android.exoplayer2.metadata.mp4.SlowMotionData) Test(org.junit.Test)

Example 52 with Segment

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

the class SegmentSpeedProviderTest method getSpeed_returnsCorrectSpeed.

@Test
public void getSpeed_returnsCorrectSpeed() {
    List<Segment> segments = ImmutableList.of(new Segment(/* startTimeMs= */
    500, /* endTimeMs= */
    1000, /* speedDivisor= */
    8), new Segment(/* startTimeMs= */
    1500, /* endTimeMs= */
    2000, /* speedDivisor= */
    4), new Segment(/* startTimeMs= */
    2000, /* endTimeMs= */
    2500, /* speedDivisor= */
    2));
    SegmentSpeedProvider provider = new SegmentSpeedProvider(new Format.Builder().setMetadata(new Metadata(new SlowMotionData(segments), SMTA_SPEED_8)).build());
    assertThat(provider.getSpeed(Util.msToUs(0))).isEqualTo(8);
    assertThat(provider.getSpeed(Util.msToUs(500))).isEqualTo(1);
    assertThat(provider.getSpeed(Util.msToUs(800))).isEqualTo(1);
    assertThat(provider.getSpeed(Util.msToUs(1000))).isEqualTo(8);
    assertThat(provider.getSpeed(Util.msToUs(1250))).isEqualTo(8);
    assertThat(provider.getSpeed(Util.msToUs(1500))).isEqualTo(2);
    assertThat(provider.getSpeed(Util.msToUs(1650))).isEqualTo(2);
    assertThat(provider.getSpeed(Util.msToUs(2000))).isEqualTo(4);
    assertThat(provider.getSpeed(Util.msToUs(2400))).isEqualTo(4);
    assertThat(provider.getSpeed(Util.msToUs(2500))).isEqualTo(8);
    assertThat(provider.getSpeed(Util.msToUs(3000))).isEqualTo(8);
}
Also used : Format(com.google.android.exoplayer2.Format) SlowMotionData(com.google.android.exoplayer2.metadata.mp4.SlowMotionData) Metadata(com.google.android.exoplayer2.metadata.Metadata) Segment(com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment) Test(org.junit.Test)

Example 53 with Segment

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

the class FragmentedMp4Extractor method onEmsgLeafAtomRead.

/**
 * Handles an emsg atom (defined in 23009-1).
 */
private void onEmsgLeafAtomRead(ParsableByteArray atom) {
    if (emsgTrackOutputs.length == 0) {
        return;
    }
    atom.setPosition(Atom.HEADER_SIZE);
    int fullAtom = atom.readInt();
    int version = Atom.parseFullAtomVersion(fullAtom);
    String schemeIdUri;
    String value;
    long timescale;
    // Only set if version == 0
    long presentationTimeDeltaUs = C.TIME_UNSET;
    long sampleTimeUs = C.TIME_UNSET;
    long durationMs;
    long id;
    switch(version) {
        case 0:
            schemeIdUri = checkNotNull(atom.readNullTerminatedString());
            value = checkNotNull(atom.readNullTerminatedString());
            timescale = atom.readUnsignedInt();
            presentationTimeDeltaUs = Util.scaleLargeTimestamp(atom.readUnsignedInt(), C.MICROS_PER_SECOND, timescale);
            if (segmentIndexEarliestPresentationTimeUs != C.TIME_UNSET) {
                sampleTimeUs = segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs;
            }
            durationMs = Util.scaleLargeTimestamp(atom.readUnsignedInt(), C.MILLIS_PER_SECOND, timescale);
            id = atom.readUnsignedInt();
            break;
        case 1:
            timescale = atom.readUnsignedInt();
            sampleTimeUs = Util.scaleLargeTimestamp(atom.readUnsignedLongToLong(), C.MICROS_PER_SECOND, timescale);
            durationMs = Util.scaleLargeTimestamp(atom.readUnsignedInt(), C.MILLIS_PER_SECOND, timescale);
            id = atom.readUnsignedInt();
            schemeIdUri = checkNotNull(atom.readNullTerminatedString());
            value = checkNotNull(atom.readNullTerminatedString());
            break;
        default:
            Log.w(TAG, "Skipping unsupported emsg version: " + version);
            return;
    }
    byte[] messageData = new byte[atom.bytesLeft()];
    atom.readBytes(messageData, /*offset=*/
    0, atom.bytesLeft());
    EventMessage eventMessage = new EventMessage(schemeIdUri, value, durationMs, id, messageData);
    ParsableByteArray encodedEventMessage = new ParsableByteArray(eventMessageEncoder.encode(eventMessage));
    int sampleSize = encodedEventMessage.bytesLeft();
    // Output the sample data.
    for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
        encodedEventMessage.setPosition(0);
        emsgTrackOutput.sampleData(encodedEventMessage, sampleSize);
    }
    // have presentation time *delta* while v1 atoms have absolute presentation time.
    if (sampleTimeUs == C.TIME_UNSET) {
        // We need the first sample timestamp in the segment before we can output the metadata.
        pendingMetadataSampleInfos.addLast(new MetadataSampleInfo(presentationTimeDeltaUs, sampleSize));
        pendingMetadataSampleBytes += sampleSize;
    } else {
        if (timestampAdjuster != null) {
            sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
        }
        for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
            emsgTrackOutput.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, /* offset= */
            0, null);
        }
    }
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) EventMessage(com.google.android.exoplayer2.metadata.emsg.EventMessage) TrackOutput(com.google.android.exoplayer2.extractor.TrackOutput)

Example 54 with Segment

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

the class HlsMediaPlaylistParserTest method parseMediaPlaylist.

@Test
public void parseMediaPlaylist() throws Exception {
    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\n" + "#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,segment title\n" + "#EXT-X-BYTERANGE:51501@2147483648\n" + "https://priv.example.com/fileSequence2680.ts\n" + "\n" + "#EXT-X-KEY:METHOD=NONE\n" + "#EXTINF:7.941,segment title .,:/# with interesting chars\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" + // Trailing comma is omitted.
    "#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" + "\n" + // 2.002 tests correct rounding, see https://github.com/google/ExoPlayer/issues/9575.
    "#EXTINF:2.002,\n" + "https://priv.example.com/fileSequence2684.ts\n" + "#EXT-X-ENDLIST";
    InputStream inputStream = new ByteArrayInputStream(Util.getUtf8Bytes(playlistString));
    HlsPlaylist playlist = new HlsPlaylistParser().parse(playlistUri, inputStream);
    HlsMediaPlaylist mediaPlaylist = (HlsMediaPlaylist) playlist;
    assertThat(mediaPlaylist.playlistType).isEqualTo(HlsMediaPlaylist.PLAYLIST_TYPE_VOD);
    assertThat(mediaPlaylist.startOffsetUs).isEqualTo(mediaPlaylist.durationUs - 25000000);
    assertThat(mediaPlaylist.mediaSequence).isEqualTo(2679);
    assertThat(mediaPlaylist.version).isEqualTo(3);
    assertThat(mediaPlaylist.hasEndTag).isTrue();
    assertThat(mediaPlaylist.protectionSchemes).isNull();
    assertThat(mediaPlaylist.targetDurationUs).isEqualTo(8000000);
    assertThat(mediaPlaylist.partTargetDurationUs).isEqualTo(C.TIME_UNSET);
    List<Segment> segments = mediaPlaylist.segments;
    assertThat(segments).isNotNull();
    assertThat(segments).hasSize(6);
    Segment segment = segments.get(0);
    assertThat(mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence).isEqualTo(4);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("");
    assertThat(segment.fullSegmentEncryptionKeyUri).isNull();
    assertThat(segment.encryptionIV).isNull();
    assertThat(segment.byteRangeLength).isEqualTo(51370);
    assertThat(segment.byteRangeOffset).isEqualTo(0);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2679.ts");
    segment = segments.get(1);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("segment title");
    assertThat(segment.fullSegmentEncryptionKeyUri).isEqualTo("https://priv.example.com/key.php?r=2680");
    assertThat(segment.encryptionIV).isEqualTo("0x1566B");
    assertThat(segment.byteRangeLength).isEqualTo(51501);
    assertThat(segment.byteRangeOffset).isEqualTo(2147483648L);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2680.ts");
    segment = segments.get(2);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0);
    assertThat(segment.durationUs).isEqualTo(7941000);
    assertThat(segment.title).isEqualTo("segment title .,:/# with interesting chars");
    assertThat(segment.fullSegmentEncryptionKeyUri).isNull();
    assertThat(segment.encryptionIV).isEqualTo(null);
    assertThat(segment.byteRangeLength).isEqualTo(51501);
    assertThat(segment.byteRangeOffset).isEqualTo(2147535149L);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2681.ts");
    segment = segments.get(3);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("");
    assertThat(segment.fullSegmentEncryptionKeyUri).isEqualTo("https://priv.example.com/key.php?r=2682");
    // 0xA7A == 2682.
    assertThat(segment.encryptionIV).isNotNull();
    assertThat(segment.encryptionIV).ignoringCase().isEqualTo("A7A");
    assertThat(segment.byteRangeLength).isEqualTo(51740);
    assertThat(segment.byteRangeOffset).isEqualTo(2147586650L);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2682.ts");
    segment = segments.get(4);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("");
    assertThat(segment.fullSegmentEncryptionKeyUri).isEqualTo("https://priv.example.com/key.php?r=2682");
    // 0xA7B == 2683.
    assertThat(segment.encryptionIV).isNotNull();
    assertThat(segment.encryptionIV).ignoringCase().isEqualTo("A7B");
    assertThat(segment.byteRangeLength).isEqualTo(C.LENGTH_UNSET);
    assertThat(segment.byteRangeOffset).isEqualTo(0);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2683.ts");
    segment = segments.get(5);
    assertThat(segment.durationUs).isEqualTo(2002000);
}
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 55 with Segment

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

the class HlsMediaPlaylistParserTest method mapTag.

@Test
public void mapTag() throws IOException {
    Uri playlistUri = Uri.parse("https://example.com/test3.m3u8");
    String playlistString = "#EXTM3U\n" + "#EXT-X-VERSION:3\n" + "#EXT-X-TARGETDURATION:5\n" + "#EXT-X-MEDIA-SEQUENCE:10\n" + "#EXTINF:5.005,\n" + "02/00/27.ts\n" + "#EXT-X-MAP:URI=\"init1.ts\"" + "#EXTINF:5.005,\n" + "02/00/32.ts\n" + "#EXTINF:5.005,\n" + "02/00/42.ts\n" + "#EXT-X-MAP:URI=\"init2.ts\"" + "#EXTINF:5.005,\n" + "02/00/47.ts\n";
    InputStream inputStream = new ByteArrayInputStream(Util.getUtf8Bytes(playlistString));
    HlsMediaPlaylist playlist = (HlsMediaPlaylist) new HlsPlaylistParser().parse(playlistUri, inputStream);
    List<Segment> segments = playlist.segments;
    assertThat(segments.get(0).initializationSegment).isNull();
    assertThat(segments.get(1).initializationSegment).isSameInstanceAs(segments.get(2).initializationSegment);
    assertThat(segments.get(1).initializationSegment.url).isEqualTo("init1.ts");
    assertThat(segments.get(3).initializationSegment.url).isEqualTo("init2.ts");
}
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)

Aggregations

Test (org.junit.Test)20 Uri (android.net.Uri)18 Segment (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment)18 Nullable (androidx.annotation.Nullable)16 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)11 ByteArrayInputStream (java.io.ByteArrayInputStream)9 IOException (java.io.IOException)9 InputStream (java.io.InputStream)9 ArrayList (java.util.ArrayList)9 HlsMediaPlaylist (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist)8 Format (com.google.android.exoplayer2.Format)6 SlowMotionData (com.google.android.exoplayer2.metadata.mp4.SlowMotionData)5 SingleSampleMediaChunk (com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk)5 RangedUri (com.google.android.exoplayer2.source.dash.manifest.RangedUri)5 Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)5 BehindLiveWindowException (com.google.android.exoplayer2.source.BehindLiveWindowException)4 ContainerMediaChunk (com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)4 Segment (com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment)4 Window (com.google.android.exoplayer2.Timeline.Window)3 Segment (com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment)3