Search in sources :

Example 16 with Representation

use of androidx.media3.exoplayer.dash.manifest.Representation in project media by androidx.

the class DashManifestParserTest method parseEssentialAndSupplementalProperties.

@Test
public void parseEssentialAndSupplementalProperties() throws IOException {
    DashManifestParser parser = new DashManifestParser();
    DashManifest manifest = parser.parse(Uri.parse("https://example.com/test.mpd"), TestUtil.getInputStream(ApplicationProvider.getApplicationContext(), SAMPLE_MPD_ESSENTIAL_SUPPLEMENTAL_PROPERTIES));
    // Verify test setup.
    assertThat(manifest.getPeriodCount()).isEqualTo(1);
    assertThat(manifest.getPeriod(0).adaptationSets).hasSize(1);
    AdaptationSet adaptationSet = manifest.getPeriod(0).adaptationSets.get(0);
    assertThat(adaptationSet.representations).hasSize(2);
    Representation representation0 = adaptationSet.representations.get(0);
    Representation representation1 = adaptationSet.representations.get(1);
    assertThat(representation0).isInstanceOf(SingleSegmentRepresentation.class);
    assertThat(representation1).isInstanceOf(MultiSegmentRepresentation.class);
    // Verify parsed properties.
    assertThat(adaptationSet.essentialProperties).hasSize(1);
    assertThat(adaptationSet.essentialProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(adaptationSet.essentialProperties.get(0).value).isEqualTo("adaptationEssential");
    assertThat(adaptationSet.supplementalProperties).hasSize(1);
    assertThat(adaptationSet.supplementalProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(adaptationSet.supplementalProperties.get(0).value).isEqualTo("adaptationSupplemental");
    assertThat(representation0.essentialProperties).hasSize(2);
    assertThat(representation0.essentialProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation0.essentialProperties.get(0).value).isEqualTo("adaptationEssential");
    assertThat(representation0.essentialProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation0.essentialProperties.get(1).value).isEqualTo("representationEssential");
    assertThat(representation0.supplementalProperties).hasSize(2);
    assertThat(representation0.supplementalProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation0.supplementalProperties.get(0).value).isEqualTo("adaptationSupplemental");
    assertThat(representation0.supplementalProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation0.supplementalProperties.get(1).value).isEqualTo("representationSupplemental");
    assertThat(representation1.essentialProperties).hasSize(2);
    assertThat(representation0.essentialProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation0.essentialProperties.get(0).value).isEqualTo("adaptationEssential");
    assertThat(representation1.essentialProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation1.essentialProperties.get(1).value).isEqualTo("representationEssential");
    assertThat(representation1.supplementalProperties).hasSize(2);
    assertThat(representation0.supplementalProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation0.supplementalProperties.get(0).value).isEqualTo("adaptationSupplemental");
    assertThat(representation1.supplementalProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation1.supplementalProperties.get(1).value).isEqualTo("representationSupplemental");
}
Also used : MultiSegmentRepresentation(androidx.media3.exoplayer.dash.manifest.Representation.MultiSegmentRepresentation) SingleSegmentRepresentation(androidx.media3.exoplayer.dash.manifest.Representation.SingleSegmentRepresentation) Test(org.junit.Test)

Example 17 with Representation

use of androidx.media3.exoplayer.dash.manifest.Representation in project media by androidx.

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 : Period(androidx.media3.exoplayer.dash.manifest.Period) MediaPeriod(androidx.media3.exoplayer.source.MediaPeriod) Representation(androidx.media3.exoplayer.dash.manifest.Representation) Nullable(androidx.annotation.Nullable)

Example 18 with Representation

use of androidx.media3.exoplayer.dash.manifest.Representation in project media by androidx.

the class DashMediaSource method getAvailableEndTimeInManifestUs.

private static long getAvailableEndTimeInManifestUs(Period period, long periodDurationUs, long nowUnixTimeUs) {
    long periodStartTimeInManifestUs = Util.msToUs(period.startMs);
    long availableEndTimeInManifestUs = Long.MAX_VALUE;
    boolean haveAudioVideoAdaptationSets = hasVideoOrAudioAdaptationSets(period);
    for (int i = 0; i < period.adaptationSets.size(); i++) {
        AdaptationSet adaptationSet = period.adaptationSets.get(i);
        List<Representation> representations = adaptationSet.representations;
        // or video adaptation set. See: https://github.com/google/ExoPlayer/issues/4029
        if ((haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT) || representations.isEmpty()) {
            continue;
        }
        @Nullable DashSegmentIndex index = representations.get(0).getIndex();
        if (index == null) {
            return periodStartTimeInManifestUs + periodDurationUs;
        }
        long availableSegmentCount = index.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs);
        if (availableSegmentCount == 0) {
            return periodStartTimeInManifestUs;
        }
        long firstAvailableSegmentNum = index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs);
        long lastAvailableSegmentNum = firstAvailableSegmentNum + availableSegmentCount - 1;
        long adaptationSetAvailableEndTimeInManifestUs = periodStartTimeInManifestUs + index.getTimeUs(lastAvailableSegmentNum) + index.getDurationUs(lastAvailableSegmentNum, periodDurationUs);
        availableEndTimeInManifestUs = min(availableEndTimeInManifestUs, adaptationSetAvailableEndTimeInManifestUs);
    }
    return availableEndTimeInManifestUs;
}
Also used : AdaptationSet(androidx.media3.exoplayer.dash.manifest.AdaptationSet) Representation(androidx.media3.exoplayer.dash.manifest.Representation) Nullable(androidx.annotation.Nullable)

Example 19 with Representation

use of androidx.media3.exoplayer.dash.manifest.Representation in project media by androidx.

the class DashUtil method loadFormatWithDrmInitData.

/**
 * Loads a {@link Format} for acquiring keys for a given period in a DASH manifest.
 *
 * @param dataSource The {@link HttpDataSource} from which data should be loaded.
 * @param period The {@link Period}.
 * @return The loaded {@link Format}, or null if none is defined.
 * @throws IOException Thrown when there is an error while loading.
 */
@Nullable
public static Format loadFormatWithDrmInitData(DataSource dataSource, Period period) throws IOException {
    @C.TrackType int primaryTrackType = C.TRACK_TYPE_VIDEO;
    Representation representation = getFirstRepresentation(period, primaryTrackType);
    if (representation == null) {
        primaryTrackType = C.TRACK_TYPE_AUDIO;
        representation = getFirstRepresentation(period, primaryTrackType);
        if (representation == null) {
            return null;
        }
    }
    Format manifestFormat = representation.format;
    @Nullable Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation);
    return sampleFormat == null ? manifestFormat : sampleFormat.withManifestFormatInfo(manifestFormat);
}
Also used : Format(androidx.media3.common.Format) Representation(androidx.media3.exoplayer.dash.manifest.Representation) Nullable(androidx.annotation.Nullable) Nullable(androidx.annotation.Nullable)

Example 20 with Representation

use of androidx.media3.exoplayer.dash.manifest.Representation in project media by androidx.

the class DashUtil method loadInitializationData.

/**
 * Loads initialization data for the {@code representation} and optionally index data then returns
 * a {@link BundledChunkExtractor} which contains the output.
 *
 * @param chunkExtractor The {@link ChunkExtractor} to use.
 * @param dataSource The source from which the data should be loaded.
 * @param representation The representation which initialization chunk belongs to.
 * @param baseUrlIndex The index of the base URL with which to resolve the request URI.
 * @param loadIndex Whether to load index data too.
 * @throws IOException Thrown when there is an error while loading.
 */
private static void loadInitializationData(ChunkExtractor chunkExtractor, DataSource dataSource, Representation representation, int baseUrlIndex, boolean loadIndex) throws IOException {
    RangedUri initializationUri = Assertions.checkNotNull(representation.getInitializationUri());
    @Nullable RangedUri requestUri;
    if (loadIndex) {
        @Nullable RangedUri indexUri = representation.getIndexUri();
        if (indexUri == null) {
            return;
        }
        // It's common for initialization and index data to be stored adjacently. Attempt to merge
        // the two requests together to request both at once.
        requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrls.get(baseUrlIndex).url);
        if (requestUri == null) {
            loadInitializationData(dataSource, representation, baseUrlIndex, chunkExtractor, initializationUri);
            requestUri = indexUri;
        }
    } else {
        requestUri = initializationUri;
    }
    loadInitializationData(dataSource, representation, baseUrlIndex, chunkExtractor, requestUri);
}
Also used : RangedUri(androidx.media3.exoplayer.dash.manifest.RangedUri) Nullable(androidx.annotation.Nullable)

Aggregations

Representation (androidx.media3.exoplayer.dash.manifest.Representation)13 Nullable (androidx.annotation.Nullable)12 RangedUri (androidx.media3.exoplayer.dash.manifest.RangedUri)7 ArrayList (java.util.ArrayList)5 Test (org.junit.Test)5 Format (androidx.media3.common.Format)4 AdaptationSet (androidx.media3.exoplayer.dash.manifest.AdaptationSet)4 StreamKey (androidx.media3.common.StreamKey)3 DataSpec (androidx.media3.datasource.DataSpec)3 MultiSegmentRepresentation (androidx.media3.exoplayer.dash.manifest.Representation.MultiSegmentRepresentation)3 SingleSegmentRepresentation (androidx.media3.exoplayer.dash.manifest.Representation.SingleSegmentRepresentation)3 SingleSegmentBase (androidx.media3.exoplayer.dash.manifest.SegmentBase.SingleSegmentBase)3 SchemeData (androidx.media3.common.DrmInitData.SchemeData)2 DashSegmentIndex (androidx.media3.exoplayer.dash.DashSegmentIndex)2 BaseUrl (androidx.media3.exoplayer.dash.manifest.BaseUrl)2 BehindLiveWindowException (androidx.media3.exoplayer.source.BehindLiveWindowException)2 ContainerMediaChunk (androidx.media3.exoplayer.source.chunk.ContainerMediaChunk)2 InitializationChunk (androidx.media3.exoplayer.source.chunk.InitializationChunk)2 SingleSampleMediaChunk (androidx.media3.exoplayer.source.chunk.SingleSampleMediaChunk)2 IOException (java.io.IOException)2