Search in sources :

Example 11 with BaseUrl

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

the class DashManifestParser method parsePeriod.

protected Pair<Period, Long> parsePeriod(XmlPullParser xpp, List<BaseUrl> parentBaseUrls, long defaultStartMs, long baseUrlAvailabilityTimeOffsetUs, long availabilityStartTimeMs, long timeShiftBufferDepthMs, boolean dvbProfileDeclared) throws XmlPullParserException, IOException {
    @Nullable String id = xpp.getAttributeValue(null, "id");
    long startMs = parseDuration(xpp, "start", defaultStartMs);
    long periodStartUnixTimeMs = availabilityStartTimeMs != C.TIME_UNSET ? availabilityStartTimeMs + startMs : C.TIME_UNSET;
    long durationMs = parseDuration(xpp, "duration", C.TIME_UNSET);
    @Nullable SegmentBase segmentBase = null;
    @Nullable Descriptor assetIdentifier = null;
    List<AdaptationSet> adaptationSets = new ArrayList<>();
    List<EventStream> eventStreams = new ArrayList<>();
    ArrayList<BaseUrl> baseUrls = new ArrayList<>();
    boolean seenFirstBaseUrl = false;
    long segmentBaseAvailabilityTimeOffsetUs = C.TIME_UNSET;
    do {
        xpp.next();
        if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) {
            if (!seenFirstBaseUrl) {
                baseUrlAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, baseUrlAvailabilityTimeOffsetUs);
                seenFirstBaseUrl = true;
            }
            baseUrls.addAll(parseBaseUrl(xpp, parentBaseUrls, dvbProfileDeclared));
        } else if (XmlPullParserUtil.isStartTag(xpp, "AdaptationSet")) {
            adaptationSets.add(parseAdaptationSet(xpp, !baseUrls.isEmpty() ? baseUrls : parentBaseUrls, segmentBase, durationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, periodStartUnixTimeMs, timeShiftBufferDepthMs, dvbProfileDeclared));
        } else if (XmlPullParserUtil.isStartTag(xpp, "EventStream")) {
            eventStreams.add(parseEventStream(xpp));
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) {
            segmentBase = parseSegmentBase(xpp, /* parent= */
            null);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
            segmentBaseAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, /* parentAvailabilityTimeOffsetUs= */
            C.TIME_UNSET);
            segmentBase = parseSegmentList(xpp, /* parent= */
            null, periodStartUnixTimeMs, durationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, timeShiftBufferDepthMs);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
            segmentBaseAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, /* parentAvailabilityTimeOffsetUs= */
            C.TIME_UNSET);
            segmentBase = parseSegmentTemplate(xpp, /* parent= */
            null, ImmutableList.of(), periodStartUnixTimeMs, durationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, timeShiftBufferDepthMs);
        } else if (XmlPullParserUtil.isStartTag(xpp, "AssetIdentifier")) {
            assetIdentifier = parseDescriptor(xpp, "AssetIdentifier");
        } else {
            maybeSkipTag(xpp);
        }
    } while (!XmlPullParserUtil.isEndTag(xpp, "Period"));
    return Pair.create(buildPeriod(id, startMs, adaptationSets, eventStreams, assetIdentifier), durationMs);
}
Also used : ArrayList(java.util.ArrayList) SingleSegmentBase(androidx.media3.exoplayer.dash.manifest.SegmentBase.SingleSegmentBase) Nullable(androidx.annotation.Nullable)

Example 12 with BaseUrl

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

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(androidx.media3.exoplayer.offline.DownloadException) RangedUri(androidx.media3.exoplayer.dash.manifest.RangedUri) Representation(androidx.media3.exoplayer.dash.manifest.Representation) IOException(java.io.IOException) DashSegmentIndex(androidx.media3.exoplayer.dash.DashSegmentIndex) Nullable(androidx.annotation.Nullable)

Example 13 with BaseUrl

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

the class BaseUrlExclusionList method selectBaseUrl.

/**
 * Selects the base URL to use from the given list.
 *
 * <p>The list is reduced by service location and priority of base URLs that have been passed to
 * {@link #exclude(BaseUrl, long)}. The base URL to use is then selected from the remaining base
 * URLs by priority and weight.
 *
 * @param baseUrls The list of {@link BaseUrl base URLs} to select from.
 * @return The selected base URL after exclusion or null if all elements have been excluded.
 */
@Nullable
public BaseUrl selectBaseUrl(List<BaseUrl> baseUrls) {
    List<BaseUrl> includedBaseUrls = applyExclusions(baseUrls);
    if (includedBaseUrls.size() < 2) {
        return Iterables.getFirst(includedBaseUrls, /* defaultValue= */
        null);
    }
    // Sort by priority and service location to make the sort order of the candidates deterministic.
    Collections.sort(includedBaseUrls, BaseUrlExclusionList::compareBaseUrl);
    // Get candidates of the lowest priority from the head of the sorted list.
    List<Pair<String, Integer>> candidateKeys = new ArrayList<>();
    int lowestPriority = includedBaseUrls.get(0).priority;
    for (int i = 0; i < includedBaseUrls.size(); i++) {
        BaseUrl baseUrl = includedBaseUrls.get(i);
        if (lowestPriority != baseUrl.priority) {
            if (candidateKeys.size() == 1) {
                // Only a single candidate of lowest priority; no choice.
                return includedBaseUrls.get(0);
            }
            break;
        }
        candidateKeys.add(new Pair<>(baseUrl.serviceLocation, baseUrl.weight));
    }
    // Check whether selection has already been taken.
    @Nullable BaseUrl baseUrl = selectionsTaken.get(candidateKeys);
    if (baseUrl == null) {
        // Weighted random selection from multiple candidates of the same priority.
        baseUrl = selectWeighted(includedBaseUrls.subList(0, candidateKeys.size()));
        // Remember the selection taken for later.
        selectionsTaken.put(candidateKeys, baseUrl);
    }
    return baseUrl;
}
Also used : ArrayList(java.util.ArrayList) BaseUrl(androidx.media3.exoplayer.dash.manifest.BaseUrl) Nullable(androidx.annotation.Nullable) Pair(android.util.Pair) Nullable(androidx.annotation.Nullable)

Example 14 with BaseUrl

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

the class BaseUrlExclusionList method selectWeighted.

private BaseUrl selectWeighted(List<BaseUrl> candidates) {
    int totalWeight = 0;
    for (int i = 0; i < candidates.size(); i++) {
        totalWeight += candidates.get(i).weight;
    }
    int randomChoice = random.nextInt(/* bound= */
    totalWeight);
    totalWeight = 0;
    for (int i = 0; i < candidates.size(); i++) {
        BaseUrl baseUrl = candidates.get(i);
        totalWeight += baseUrl.weight;
        if (randomChoice < totalWeight) {
            return baseUrl;
        }
    }
    return Iterables.getLast(candidates);
}
Also used : BaseUrl(androidx.media3.exoplayer.dash.manifest.BaseUrl)

Example 15 with BaseUrl

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

the class BaseUrlExclusionList method applyExclusions.

// Internal methods.
private List<BaseUrl> applyExclusions(List<BaseUrl> baseUrls) {
    long nowMs = SystemClock.elapsedRealtime();
    removeExpiredExclusions(nowMs, excludedServiceLocations);
    removeExpiredExclusions(nowMs, excludedPriorities);
    List<BaseUrl> includedBaseUrls = new ArrayList<>();
    for (int i = 0; i < baseUrls.size(); i++) {
        BaseUrl baseUrl = baseUrls.get(i);
        if (!excludedServiceLocations.containsKey(baseUrl.serviceLocation) && !excludedPriorities.containsKey(baseUrl.priority)) {
            includedBaseUrls.add(baseUrl);
        }
    }
    return includedBaseUrls;
}
Also used : ArrayList(java.util.ArrayList) BaseUrl(androidx.media3.exoplayer.dash.manifest.BaseUrl)

Aggregations

BaseUrl (androidx.media3.exoplayer.dash.manifest.BaseUrl)17 Test (org.junit.Test)14 Nullable (androidx.annotation.Nullable)7 ArrayList (java.util.ArrayList)6 Random (java.util.Random)5 Format (androidx.media3.common.Format)3 SingleSegmentBase (androidx.media3.exoplayer.dash.manifest.SegmentBase.SingleSegmentBase)3 LoadErrorHandlingPolicy (androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy)3 IOException (java.io.IOException)3 Uri (android.net.Uri)2 SystemClock (android.os.SystemClock)2 Pair (android.util.Pair)2 C (androidx.media3.common.C)2 TrackGroup (androidx.media3.common.TrackGroup)2 Assertions (androidx.media3.common.util.Assertions)2 Assertions.checkNotNull (androidx.media3.common.util.Assertions.checkNotNull)2 Util (androidx.media3.common.util.Util)2 DataSpec (androidx.media3.datasource.DataSpec)2 HttpDataSource (androidx.media3.datasource.HttpDataSource)2 PlayerId (androidx.media3.exoplayer.analytics.PlayerId)2