Search in sources :

Example 1 with AdaptationSet

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

the class OfflineLicenseHelper method download.

/**
   * Downloads an offline license.
   *
   * @param dataSource The {@link HttpDataSource} to be used for download.
   * @param dashManifest The {@link DashManifest} of the DASH content.
   * @return The downloaded offline license key set id.
   * @throws IOException If an error occurs reading data from the stream.
   * @throws InterruptedException If the thread has been interrupted.
   * @throws DrmSessionException Thrown when there is an error during DRM session.
   */
public byte[] download(HttpDataSource dataSource, DashManifest dashManifest) throws IOException, InterruptedException, DrmSessionException {
    // as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
    if (dashManifest.getPeriodCount() < 1) {
        return null;
    }
    Period period = dashManifest.getPeriod(0);
    int adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_VIDEO);
    if (adaptationSetIndex == C.INDEX_UNSET) {
        adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_AUDIO);
        if (adaptationSetIndex == C.INDEX_UNSET) {
            return null;
        }
    }
    AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
    if (adaptationSet.representations.isEmpty()) {
        return null;
    }
    Representation representation = adaptationSet.representations.get(0);
    DrmInitData drmInitData = representation.format.drmInitData;
    if (drmInitData == null) {
        Format sampleFormat = DashUtil.loadSampleFormat(dataSource, representation);
        if (sampleFormat != null) {
            drmInitData = sampleFormat.drmInitData;
        }
        if (drmInitData == null) {
            return null;
        }
    }
    blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, drmInitData);
    return drmSessionManager.getOfflineLicenseKeySetId();
}
Also used : Format(com.google.android.exoplayer2.Format) Period(com.google.android.exoplayer2.source.dash.manifest.Period) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation)

Example 2 with AdaptationSet

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

the class DashManifestParser method parsePeriod.

protected Pair<Period, Long> parsePeriod(XmlPullParser xpp, String baseUrl, long defaultStartMs) throws XmlPullParserException, IOException {
    String id = xpp.getAttributeValue(null, "id");
    long startMs = parseDuration(xpp, "start", defaultStartMs);
    long durationMs = parseDuration(xpp, "duration", C.TIME_UNSET);
    SegmentBase segmentBase = null;
    List<AdaptationSet> adaptationSets = new ArrayList<>();
    boolean seenFirstBaseUrl = false;
    do {
        xpp.next();
        if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) {
            if (!seenFirstBaseUrl) {
                baseUrl = parseBaseUrl(xpp, baseUrl);
                seenFirstBaseUrl = true;
            }
        } else if (XmlPullParserUtil.isStartTag(xpp, "AdaptationSet")) {
            adaptationSets.add(parseAdaptationSet(xpp, baseUrl, segmentBase));
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) {
            segmentBase = parseSegmentBase(xpp, null);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
            segmentBase = parseSegmentList(xpp, null);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
            segmentBase = parseSegmentTemplate(xpp, null);
        }
    } while (!XmlPullParserUtil.isEndTag(xpp, "Period"));
    return Pair.create(buildPeriod(id, startMs, adaptationSets), durationMs);
}
Also used : SingleSegmentBase(com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase) ArrayList(java.util.ArrayList)

Example 3 with AdaptationSet

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

the class DashMediaPeriod method buildTrackGroups.

// Internal methods.
private static Pair<TrackGroupArray, EmbeddedTrackInfo[]> buildTrackGroups(List<AdaptationSet> adaptationSets) {
    int adaptationSetCount = adaptationSets.size();
    int embeddedTrackCount = getEmbeddedTrackCount(adaptationSets);
    TrackGroup[] trackGroupArray = new TrackGroup[adaptationSetCount + embeddedTrackCount];
    EmbeddedTrackInfo[] embeddedTrackInfos = new EmbeddedTrackInfo[embeddedTrackCount];
    int embeddedTrackIndex = 0;
    for (int i = 0; i < adaptationSetCount; i++) {
        AdaptationSet adaptationSet = adaptationSets.get(i);
        List<Representation> representations = adaptationSet.representations;
        Format[] formats = new Format[representations.size()];
        for (int j = 0; j < formats.length; j++) {
            formats[j] = representations.get(j).format;
        }
        trackGroupArray[i] = new TrackGroup(formats);
        if (hasEventMessageTrack(adaptationSet)) {
            Format format = Format.createSampleFormat(adaptationSet.id + ":emsg", MimeTypes.APPLICATION_EMSG, null, Format.NO_VALUE, null);
            trackGroupArray[adaptationSetCount + embeddedTrackIndex] = new TrackGroup(format);
            embeddedTrackInfos[embeddedTrackIndex++] = new EmbeddedTrackInfo(i, C.TRACK_TYPE_METADATA);
        }
        if (hasCea608Track(adaptationSet)) {
            Format format = Format.createTextSampleFormat(adaptationSet.id + ":cea608", MimeTypes.APPLICATION_CEA608, null, Format.NO_VALUE, 0, null, null);
            trackGroupArray[adaptationSetCount + embeddedTrackIndex] = new TrackGroup(format);
            embeddedTrackInfos[embeddedTrackIndex++] = new EmbeddedTrackInfo(i, C.TRACK_TYPE_TEXT);
        }
    }
    return Pair.create(new TrackGroupArray(trackGroupArray), embeddedTrackInfos);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation)

Example 4 with AdaptationSet

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

the class DashDownloadTest method downloadContent.

private DashDownloader downloadContent() throws Exception {
    DashManifest dashManifest = DashUtil.loadManifest(httpDataSourceFactory.createDataSource(), MANIFEST_URI);
    ArrayList<StreamKey> keys = new ArrayList<>();
    for (int pIndex = 0; pIndex < dashManifest.getPeriodCount(); pIndex++) {
        List<AdaptationSet> adaptationSets = dashManifest.getPeriod(pIndex).adaptationSets;
        for (int aIndex = 0; aIndex < adaptationSets.size(); aIndex++) {
            AdaptationSet adaptationSet = adaptationSets.get(aIndex);
            List<Representation> representations = adaptationSet.representations;
            for (int rIndex = 0; rIndex < representations.size(); rIndex++) {
                String id = representations.get(rIndex).format.id;
                if (DashTestData.AAC_AUDIO_REPRESENTATION_ID.equals(id) || DashTestData.H264_CDD_FIXED.equals(id)) {
                    keys.add(new StreamKey(pIndex, aIndex, rIndex));
                }
            }
        }
    }
    CacheDataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory().setCache(cache).setUpstreamDataSourceFactory(httpDataSourceFactory);
    return new DashDownloader(new MediaItem.Builder().setUri(MANIFEST_URI).setStreamKeys(keys).build(), cacheDataSourceFactory);
}
Also used : DashDownloader(com.google.android.exoplayer2.source.dash.offline.DashDownloader) DashManifest(com.google.android.exoplayer2.source.dash.manifest.DashManifest) ArrayList(java.util.ArrayList) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation) CacheDataSource(com.google.android.exoplayer2.upstream.cache.CacheDataSource) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) StreamKey(com.google.android.exoplayer2.offline.StreamKey)

Example 5 with AdaptationSet

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

the class DashMediaPeriod method getGroupedAdaptationSetIndices.

/**
 * Groups adaptation sets. Two adaptations sets belong to the same group if either:
 *
 * <ul>
 *   <li>One is a trick-play adaptation set and uses a {@code
 *       http://dashif.org/guidelines/trickmode} essential or supplemental property to indicate
 *       that the other is the main adaptation set to which it corresponds.
 *   <li>The two adaptation sets are marked as safe for switching using {@code
 *       urn:mpeg:dash:adaptation-set-switching:2016} supplemental properties.
 * </ul>
 *
 * @param adaptationSets The adaptation sets to merge.
 * @return An array of groups, where each group is an array of adaptation set indices.
 */
private static int[][] getGroupedAdaptationSetIndices(List<AdaptationSet> adaptationSets) {
    int adaptationSetCount = adaptationSets.size();
    SparseIntArray adaptationSetIdToIndex = new SparseIntArray(adaptationSetCount);
    List<List<Integer>> adaptationSetGroupedIndices = new ArrayList<>(adaptationSetCount);
    SparseArray<List<Integer>> adaptationSetIndexToGroupedIndices = new SparseArray<>(adaptationSetCount);
    // adaptationSetIdToIndex map.
    for (int i = 0; i < adaptationSetCount; i++) {
        adaptationSetIdToIndex.put(adaptationSets.get(i).id, i);
        List<Integer> initialGroup = new ArrayList<>();
        initialGroup.add(i);
        adaptationSetGroupedIndices.add(initialGroup);
        adaptationSetIndexToGroupedIndices.put(i, initialGroup);
    }
    // Merge adaptation set groups.
    for (int i = 0; i < adaptationSetCount; i++) {
        int mergedGroupIndex = i;
        AdaptationSet adaptationSet = adaptationSets.get(i);
        // Trick-play adaptation sets are merged with their corresponding main adaptation sets.
        @Nullable Descriptor trickPlayProperty = findTrickPlayProperty(adaptationSet.essentialProperties);
        if (trickPlayProperty == null) {
            // Trick-play can also be specified using a supplemental property.
            trickPlayProperty = findTrickPlayProperty(adaptationSet.supplementalProperties);
        }
        if (trickPlayProperty != null) {
            int mainAdaptationSetId = Integer.parseInt(trickPlayProperty.value);
            int mainAdaptationSetIndex = adaptationSetIdToIndex.get(mainAdaptationSetId, /* valueIfKeyNotFound= */
            -1);
            if (mainAdaptationSetIndex != -1) {
                mergedGroupIndex = mainAdaptationSetIndex;
            }
        }
        // merged group.
        if (mergedGroupIndex == i) {
            @Nullable Descriptor adaptationSetSwitchingProperty = findAdaptationSetSwitchingProperty(adaptationSet.supplementalProperties);
            if (adaptationSetSwitchingProperty != null) {
                String[] otherAdaptationSetIds = Util.split(adaptationSetSwitchingProperty.value, ",");
                for (String adaptationSetId : otherAdaptationSetIds) {
                    int otherAdaptationSetId = adaptationSetIdToIndex.get(Integer.parseInt(adaptationSetId), /* valueIfKeyNotFound= */
                    -1);
                    if (otherAdaptationSetId != -1) {
                        mergedGroupIndex = min(mergedGroupIndex, otherAdaptationSetId);
                    }
                }
            }
        }
        // Merge the groups if necessary.
        if (mergedGroupIndex != i) {
            List<Integer> thisGroup = adaptationSetIndexToGroupedIndices.get(i);
            List<Integer> mergedGroup = adaptationSetIndexToGroupedIndices.get(mergedGroupIndex);
            mergedGroup.addAll(thisGroup);
            adaptationSetIndexToGroupedIndices.put(i, mergedGroup);
            adaptationSetGroupedIndices.remove(thisGroup);
        }
    }
    int[][] groupedAdaptationSetIndices = new int[adaptationSetGroupedIndices.size()][];
    for (int i = 0; i < groupedAdaptationSetIndices.length; i++) {
        groupedAdaptationSetIndices[i] = Ints.toArray(adaptationSetGroupedIndices.get(i));
        // Restore the original adaptation set order within each group.
        Arrays.sort(groupedAdaptationSetIndices[i]);
    }
    return groupedAdaptationSetIndices;
}
Also used : ArrayList(java.util.ArrayList) SparseArray(android.util.SparseArray) SparseIntArray(android.util.SparseIntArray) Descriptor(com.google.android.exoplayer2.source.dash.manifest.Descriptor) List(java.util.List) ArrayList(java.util.ArrayList) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) Nullable(androidx.annotation.Nullable)

Aggregations

AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)16 Format (com.google.android.exoplayer2.Format)9 ArrayList (java.util.ArrayList)9 Test (org.junit.Test)9 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)8 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)7 Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)7 DashManifest (com.google.android.exoplayer2.source.dash.manifest.DashManifest)6 Nullable (androidx.annotation.Nullable)5 StreamKey (com.google.android.exoplayer2.offline.StreamKey)4 MultiSegmentRepresentation (com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation)3 SingleSegmentRepresentation (com.google.android.exoplayer2.source.dash.manifest.Representation.SingleSegmentRepresentation)3 Descriptor (com.google.android.exoplayer2.source.dash.manifest.Descriptor)2 Period (com.google.android.exoplayer2.source.dash.manifest.Period)2 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)2 SparseArray (android.util.SparseArray)1 SparseIntArray (android.util.SparseIntArray)1 DownloadException (com.google.android.exoplayer2.offline.DownloadException)1 ChunkSampleStream (com.google.android.exoplayer2.source.chunk.ChunkSampleStream)1 DashSegmentIndex (com.google.android.exoplayer2.source.dash.DashSegmentIndex)1