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();
}
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);
}
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);
}
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);
}
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;
}
Aggregations