Search in sources :

Example 26 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashDownloader method addSegmentsForAdaptationSet.

private void addSegmentsForAdaptationSet(DataSource dataSource, AdaptationSet adaptationSet, long periodStartUs, long periodDurationUs, boolean removing, ArrayList<Segment> out) throws IOException, InterruptedException {
    for (int i = 0; i < adaptationSet.representations.size(); i++) {
        Representation representation = adaptationSet.representations.get(i);
        DashSegmentIndex index;
        try {
            index = getSegmentIndex(dataSource, adaptationSet.type, representation, removing);
            if (index == null) {
                // Loading succeeded but there was no index.
                throw new DownloadException("Missing segment index");
            }
        } catch (IOException e) {
            if (!removing) {
                throw e;
            }
            // Generating an incomplete segment list is allowed. Advance to the next representation.
            continue;
        }
        long segmentCount = index.getSegmentCount(periodDurationUs);
        if (segmentCount == DashSegmentIndex.INDEX_UNBOUNDED) {
            throw new DownloadException("Unbounded segment index");
        }
        String baseUrl = castNonNull(baseUrlExclusionList.selectBaseUrl(representation.baseUrls)).url;
        @Nullable RangedUri initializationUri = representation.getInitializationUri();
        if (initializationUri != null) {
            out.add(createSegment(representation, baseUrl, periodStartUs, initializationUri));
        }
        @Nullable RangedUri indexUri = representation.getIndexUri();
        if (indexUri != null) {
            out.add(createSegment(representation, baseUrl, periodStartUs, indexUri));
        }
        long firstSegmentNum = index.getFirstSegmentNum();
        long lastSegmentNum = firstSegmentNum + segmentCount - 1;
        for (long j = firstSegmentNum; j <= lastSegmentNum; j++) {
            out.add(createSegment(representation, baseUrl, periodStartUs + index.getTimeUs(j), index.getSegmentUrl(j)));
        }
    }
}
Also used : DownloadException(com.google.android.exoplayer2.offline.DownloadException) RangedUri(com.google.android.exoplayer2.source.dash.manifest.RangedUri) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation) IOException(java.io.IOException) DashSegmentIndex(com.google.android.exoplayer2.source.dash.DashSegmentIndex) Nullable(androidx.annotation.Nullable)

Example 27 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashManifestTest method copy.

@Test
public void copy() {
    Representation[][][] representations = newRepresentations(3, 2, 3);
    ServiceDescriptionElement serviceDescriptionElement = new ServiceDescriptionElement(/* targetOffsetMs= */
    20, /* minOffsetMs= */
    10, /* maxOffsetMs= */
    40, /* minPlaybackSpeed= */
    0.9f, /* maxPlaybackSpeed= */
    1.1f);
    DashManifest sourceManifest = newDashManifest(10, serviceDescriptionElement, newPeriod("1", 1, newAdaptationSet(2, representations[0][0]), newAdaptationSet(3, representations[0][1])), newPeriod("4", 4, newAdaptationSet(5, representations[1][0]), newAdaptationSet(6, representations[1][1])), newPeriod("7", 7, newAdaptationSet(8, representations[2][0]), newAdaptationSet(9, representations[2][1])));
    List<StreamKey> keys = Arrays.asList(new StreamKey(0, 0, 0), new StreamKey(0, 0, 1), new StreamKey(0, 1, 2), new StreamKey(1, 0, 1), new StreamKey(1, 1, 0), new StreamKey(1, 1, 2), new StreamKey(2, 0, 1), new StreamKey(2, 0, 2), new StreamKey(2, 1, 0));
    // Keys don't need to be in any particular order
    Collections.shuffle(keys, new Random(0));
    DashManifest copyManifest = sourceManifest.copy(keys);
    DashManifest expectedManifest = newDashManifest(10, serviceDescriptionElement, newPeriod("1", 1, newAdaptationSet(2, representations[0][0][0], representations[0][0][1]), newAdaptationSet(3, representations[0][1][2])), newPeriod("4", 4, newAdaptationSet(5, representations[1][0][1]), newAdaptationSet(6, representations[1][1][0], representations[1][1][2])), newPeriod("7", 7, newAdaptationSet(8, representations[2][0][1], representations[2][0][2]), newAdaptationSet(9, representations[2][1][0])));
    assertManifestEquals(expectedManifest, copyManifest);
}
Also used : Random(java.util.Random) StreamKey(com.google.android.exoplayer2.offline.StreamKey) Test(org.junit.Test)

Example 28 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashManifestParserTest method parseMediaPresentationDescription_segmentTemplate.

@Test
public void parseMediaPresentationDescription_segmentTemplate() throws IOException {
    DashManifestParser parser = new DashManifestParser();
    DashManifest manifest = parser.parse(Uri.parse("https://example.com/test.mpd"), TestUtil.getInputStream(ApplicationProvider.getApplicationContext(), SAMPLE_MPD_SEGMENT_TEMPLATE));
    assertThat(manifest.getPeriodCount()).isEqualTo(1);
    Period period = manifest.getPeriod(0);
    assertThat(period).isNotNull();
    assertThat(period.adaptationSets).hasSize(2);
    for (AdaptationSet adaptationSet : period.adaptationSets) {
        assertThat(adaptationSet).isNotNull();
        for (Representation representation : adaptationSet.representations) {
            if (representation instanceof Representation.MultiSegmentRepresentation) {
                Representation.MultiSegmentRepresentation multiSegmentRepresentation = (Representation.MultiSegmentRepresentation) representation;
                long firstSegmentIndex = multiSegmentRepresentation.getFirstSegmentNum();
                RangedUri uri = multiSegmentRepresentation.getSegmentUrl(firstSegmentIndex);
                assertThat(uri.resolveUriString(representation.baseUrls.get(0).url)).contains("redirector.googlevideo.com");
            }
        }
    }
}
Also used : SingleSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.SingleSegmentRepresentation) MultiSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation) MultiSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation) MultiSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation) Test(org.junit.Test)

Example 29 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashManifestParserTest method getAvailabilityTimeOffsetUs.

private static long getAvailabilityTimeOffsetUs(AdaptationSet adaptationSet) {
    assertThat(adaptationSet.representations).isNotEmpty();
    Representation representation = adaptationSet.representations.get(0);
    assertThat(representation).isInstanceOf(Representation.MultiSegmentRepresentation.class);
    SegmentBase.MultiSegmentBase segmentBase = ((Representation.MultiSegmentRepresentation) representation).segmentBase;
    return segmentBase.availabilityTimeOffsetUs;
}
Also used : SingleSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.SingleSegmentRepresentation) MultiSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation) MultiSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation)

Example 30 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashMediaSource method getIntervalUntilNextManifestRefreshMs.

private static long getIntervalUntilNextManifestRefreshMs(DashManifest manifest, long nowUnixTimeMs) {
    int periodIndex = manifest.getPeriodCount() - 1;
    Period period = manifest.getPeriod(periodIndex);
    long periodStartUs = Util.msToUs(period.startMs);
    long periodDurationUs = manifest.getPeriodDurationUs(periodIndex);
    long nowUnixTimeUs = Util.msToUs(nowUnixTimeMs);
    long availabilityStartTimeUs = Util.msToUs(manifest.availabilityStartTimeMs);
    long intervalUs = Util.msToUs(DEFAULT_NOTIFY_MANIFEST_INTERVAL_MS);
    for (int i = 0; i < period.adaptationSets.size(); i++) {
        List<Representation> representations = period.adaptationSets.get(i).representations;
        if (representations.isEmpty()) {
            continue;
        }
        @Nullable DashSegmentIndex index = representations.get(0).getIndex();
        if (index != null) {
            long nextSegmentShiftUnixTimeUs = availabilityStartTimeUs + periodStartUs + index.getNextSegmentAvailableTimeUs(periodDurationUs, nowUnixTimeUs);
            long requiredIntervalUs = nextSegmentShiftUnixTimeUs - nowUnixTimeUs;
            // Avoid multiple refreshes within a very small amount of time.
            if (requiredIntervalUs < intervalUs - 100_000 || (requiredIntervalUs > intervalUs && requiredIntervalUs < intervalUs + 100_000)) {
                intervalUs = requiredIntervalUs;
            }
        }
    }
    // Round up to compensate for a potential loss in the us to ms conversion.
    return LongMath.divide(intervalUs, 1000, RoundingMode.CEILING);
}
Also used : MediaPeriod(com.google.android.exoplayer2.source.MediaPeriod) Period(com.google.android.exoplayer2.source.dash.manifest.Period) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation) Nullable(androidx.annotation.Nullable)

Aggregations

Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)18 Nullable (androidx.annotation.Nullable)12 RangedUri (com.google.android.exoplayer2.source.dash.manifest.RangedUri)10 Format (com.google.android.exoplayer2.Format)9 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)7 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)6 ArrayList (java.util.ArrayList)6 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)5 Test (org.junit.Test)5 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)4 StreamKey (com.google.android.exoplayer2.offline.StreamKey)3 BehindLiveWindowException (com.google.android.exoplayer2.source.BehindLiveWindowException)3 ContainerMediaChunk (com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)3 InitializationChunk (com.google.android.exoplayer2.source.chunk.InitializationChunk)3 SingleSampleMediaChunk (com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk)3 MultiSegmentRepresentation (com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation)3 IOException (java.io.IOException)3 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)2 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)2 DashSegmentIndex (com.google.android.exoplayer2.source.dash.DashSegmentIndex)2