use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.
the class DashUtilTest method resolveCacheKey_representationCacheKeyDefined_usesRepresentationCacheKey.
@Test
public void resolveCacheKey_representationCacheKeyDefined_usesRepresentationCacheKey() {
ImmutableList<BaseUrl> baseUrls = ImmutableList.of(new BaseUrl("http://www.google.com"), new BaseUrl("http://www.foo.com"));
Representation.SingleSegmentRepresentation representation = new Representation.SingleSegmentRepresentation(/* revisionId= */
1L, new Format.Builder().build(), baseUrls, new SingleSegmentBase(), /* inbandEventStreams= */
null, /* essentialProperties= */
ImmutableList.of(), /* supplementalProperties= */
ImmutableList.of(), "cacheKey", /* contentLength= */
1);
RangedUri rangedUri = new RangedUri("path/to/resource", /* start= */
0, /* length= */
1);
String cacheKey = DashUtil.resolveCacheKey(representation, rangedUri);
assertThat(cacheKey).isEqualTo("cacheKey");
}
use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.
the class DashDownloader method getSegmentIndex.
@Nullable
private DashSegmentIndex getSegmentIndex(DataSource dataSource, int trackType, Representation representation, boolean removing) throws IOException, InterruptedException {
DashSegmentIndex index = representation.getIndex();
if (index != null) {
return index;
}
RunnableFutureTask<@NullableType ChunkIndex, IOException> runnable = new RunnableFutureTask<@NullableType ChunkIndex, IOException>() {
@Override
@NullableType
protected ChunkIndex doWork() throws IOException {
return DashUtil.loadChunkIndex(dataSource, trackType, representation);
}
};
@Nullable ChunkIndex seekMap = execute(runnable, removing);
return seekMap == null ? null : new DashWrappingSegmentIndex(seekMap, representation.presentationTimeOffsetUs);
}
use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.
the class DashManifestParser method buildRepresentation.
protected Representation buildRepresentation(RepresentationInfo representationInfo, @Nullable String label, @Nullable String extraDrmSchemeType, ArrayList<SchemeData> extraDrmSchemeDatas, ArrayList<Descriptor> extraInbandEventStreams) {
Format.Builder formatBuilder = representationInfo.format.buildUpon();
if (label != null) {
formatBuilder.setLabel(label);
}
@Nullable String drmSchemeType = representationInfo.drmSchemeType;
if (drmSchemeType == null) {
drmSchemeType = extraDrmSchemeType;
}
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
drmSchemeDatas.addAll(extraDrmSchemeDatas);
if (!drmSchemeDatas.isEmpty()) {
filterRedundantIncompleteSchemeDatas(drmSchemeDatas);
formatBuilder.setDrmInitData(new DrmInitData(drmSchemeType, drmSchemeDatas));
}
ArrayList<Descriptor> inbandEventStreams = representationInfo.inbandEventStreams;
inbandEventStreams.addAll(extraInbandEventStreams);
return Representation.newInstance(representationInfo.revisionId, formatBuilder.build(), representationInfo.baseUrls, representationInfo.segmentBase, inbandEventStreams, representationInfo.essentialProperties, representationInfo.supplementalProperties, /* cacheKey= */
null);
}
use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.
the class DashManifestParser method parseRepresentation.
// Representation parsing.
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, List<BaseUrl> parentBaseUrls, @Nullable String adaptationSetMimeType, @Nullable String adaptationSetCodecs, int adaptationSetWidth, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, @Nullable String adaptationSetLanguage, List<Descriptor> adaptationSetRoleDescriptors, List<Descriptor> adaptationSetAccessibilityDescriptors, List<Descriptor> adaptationSetEssentialProperties, List<Descriptor> adaptationSetSupplementalProperties, @Nullable SegmentBase segmentBase, long periodStartUnixTimeMs, long periodDurationMs, long baseUrlAvailabilityTimeOffsetUs, long segmentBaseAvailabilityTimeOffsetUs, long timeShiftBufferDepthMs, boolean dvbProfileDeclared) throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id");
int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
String mimeType = parseString(xpp, "mimeType", adaptationSetMimeType);
String codecs = parseString(xpp, "codecs", adaptationSetCodecs);
int width = parseInt(xpp, "width", adaptationSetWidth);
int height = parseInt(xpp, "height", adaptationSetHeight);
float frameRate = parseFrameRate(xpp, adaptationSetFrameRate);
int audioChannels = adaptationSetAudioChannels;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", adaptationSetAudioSamplingRate);
String drmSchemeType = null;
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
ArrayList<Descriptor> essentialProperties = new ArrayList<>(adaptationSetEssentialProperties);
ArrayList<Descriptor> supplementalProperties = new ArrayList<>(adaptationSetSupplementalProperties);
ArrayList<BaseUrl> baseUrls = new ArrayList<>();
boolean seenFirstBaseUrl = false;
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, "AudioChannelConfiguration")) {
audioChannels = parseAudioChannelConfiguration(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) {
segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
segmentBaseAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, segmentBaseAvailabilityTimeOffsetUs);
segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase, periodStartUnixTimeMs, periodDurationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, timeShiftBufferDepthMs);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBaseAvailabilityTimeOffsetUs = parseAvailabilityTimeOffsetUs(xpp, segmentBaseAvailabilityTimeOffsetUs);
segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase, adaptationSetSupplementalProperties, periodStartUnixTimeMs, periodDurationMs, baseUrlAvailabilityTimeOffsetUs, segmentBaseAvailabilityTimeOffsetUs, timeShiftBufferDepthMs);
} else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) {
Pair<String, SchemeData> contentProtection = parseContentProtection(xpp);
if (contentProtection.first != null) {
drmSchemeType = contentProtection.first;
}
if (contentProtection.second != null) {
drmSchemeDatas.add(contentProtection.second);
}
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
} else if (XmlPullParserUtil.isStartTag(xpp, "EssentialProperty")) {
essentialProperties.add(parseDescriptor(xpp, "EssentialProperty"));
} else if (XmlPullParserUtil.isStartTag(xpp, "SupplementalProperty")) {
supplementalProperties.add(parseDescriptor(xpp, "SupplementalProperty"));
} else {
maybeSkipTag(xpp);
}
} while (!XmlPullParserUtil.isEndTag(xpp, "Representation"));
Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetRoleDescriptors, adaptationSetAccessibilityDescriptors, codecs, essentialProperties, supplementalProperties);
segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase();
return new RepresentationInfo(format, !baseUrls.isEmpty() ? baseUrls : parentBaseUrls, segmentBase, drmSchemeType, drmSchemeDatas, inbandEventStreams, essentialProperties, supplementalProperties, Representation.REVISION_ID_DEFAULT);
}
use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.
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;
}
Aggregations