private Map<String, TtmlStyle> parseHeader(XmlPullParser xmlParser, Map<String, TtmlStyle> globalStyles, Map<String, TtmlRegion> globalRegions) throws IOException, XmlPullParserException { do { xmlParser.next(); if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_STYLE)) { String parentStyleId = XmlPullParserUtil.getAttributeValue(xmlParser, ATTR_STYLE); TtmlStyle style = parseStyleAttributes(xmlParser, new TtmlStyle()); if (parentStyleId != null) { for (String id : parseStyleIds(parentStyleId)) { style.chain(globalStyles.get(id)); } } if (style.getId() != null) { globalStyles.put(style.getId(), style); } } else if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_REGION)) { TtmlRegion ttmlRegion = parseRegionAttributes(xmlParser); if (ttmlRegion != null) { globalRegions.put(ttmlRegion.id, ttmlRegion); } } } while (!XmlPullParserUtil.isEndTag(xmlParser, TtmlNode.TAG_HEAD)); return globalStyles; }
private Map<String, TtmlStyle> parseHeader(XmlPullParser xmlParser, Map<String, TtmlStyle> globalStyles, Map<String, TtmlRegion> globalRegions) throws IOException, XmlPullParserException { do { xmlParser.next(); if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_STYLE)) { String parentStyleId = XmlPullParserUtil.getAttributeValue(xmlParser, ATTR_STYLE); TtmlStyle style = parseStyleAttributes(xmlParser, new TtmlStyle()); if (parentStyleId != null) { for (String id : parseStyleIds(parentStyleId)) { style.chain(globalStyles.get(id)); } } if (style.getId() != null) { globalStyles.put(style.getId(), style); } } else if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_REGION)) { Pair<String, TtmlRegion> ttmlRegionInfo = parseRegionAttributes(xmlParser); if (ttmlRegionInfo != null) { globalRegions.put(ttmlRegionInfo.first, ttmlRegionInfo.second); } } } while (!XmlPullParserUtil.isEndTag(xmlParser, TtmlNode.TAG_HEAD)); return globalStyles; }
protected List<SegmentTimelineElement> parseSegmentTimeline(XmlPullParser xpp) throws XmlPullParserException, IOException { List<SegmentTimelineElement> segmentTimeline = new ArrayList<>(); long elapsedTime = 0; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "S")) { elapsedTime = parseLong(xpp, "t", elapsedTime); long duration = parseLong(xpp, "d", C.TIME_UNSET); int count = 1 + parseInt(xpp, "r", 0); for (int i = 0; i < count; i++) { segmentTimeline.add(buildSegmentTimelineElement(elapsedTime, duration)); elapsedTime += duration; } } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentTimeline")); return segmentTimeline; }
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); }
/** * Parses a ContentProtection element. * * @param xpp The parser from which to read. * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. * @return {@link SchemeData} parsed from the ContentProtection element, or null if the element is * unsupported. */ protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri"); boolean isPlayReady = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95".equals(schemeIdUri); byte[] data = null; UUID uuid = null; boolean requiresSecureDecoder = false; do { xpp.next(); if (data == null && XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) { // The cenc:pssh element is defined in 23001-7:2015. data = Base64.decode(xpp.getText(), Base64.DEFAULT); uuid = PsshAtomUtil.parseUuid(data); if (uuid == null) { Log.w(TAG, "Skipping malformed cenc:pssh data"); data = null; } } else if (data == null && isPlayReady && XmlPullParserUtil.isStartTag(xpp, "mspr:pro") && xpp.next() == XmlPullParser.TEXT) { // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady. data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID, Base64.decode(xpp.getText(), Base64.DEFAULT)); uuid = C.PLAYREADY_UUID; } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) { String robustnessLevel = xpp.getAttributeValue(null, "robustness_level"); requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW"); } } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection")); return data != null ? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null; }
/** * Parses a Role element. * * @param xpp The parser from which to read. * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. * @return {@link C.SelectionFlags} parsed from the element. */ protected int parseRole(XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeIdUri = parseString(xpp, "schemeIdUri", null); String value = parseString(xpp, "value", null); do { xpp.next(); } while (!XmlPullParserUtil.isEndTag(xpp, "Role")); return "urn:mpeg:dash:role:2011".equals(schemeIdUri) && "main".equals(value) ? C.SELECTION_FLAG_DEFAULT : 0; }
protected SingleSegmentBase parseSegmentBase(XmlPullParser xpp, SingleSegmentBase parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", parent != null ? parent.presentationTimeOffset : 0); long indexStart = parent != null ? parent.indexStart : 0; long indexLength = parent != null ? parent.indexLength : 0; String indexRangeText = xpp.getAttributeValue(null, "indexRange"); if (indexRangeText != null) { String[] indexRange = indexRangeText.split("-"); indexStart = Long.parseLong(indexRange[0]); indexLength = Long.parseLong(indexRange[1]) - indexStart + 1; } RangedUri initialization = parent != null ? parent.initialization : null; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentBase")); return buildSingleSegmentBase(initialization, timescale, presentationTimeOffset, indexStart, indexLength); }
protected SegmentList parseSegmentList(XmlPullParser xpp, SegmentList parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", parent != null ? parent.presentationTimeOffset : 0); long duration = parseLong(xpp, "duration", parent != null ? parent.duration : C.TIME_UNSET); int startNumber = parseInt(xpp, "startNumber", parent != null ? parent.startNumber : 1); RangedUri initialization = null; List<SegmentTimelineElement> timeline = null; List<RangedUri> segments = null; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTimeline")) { timeline = parseSegmentTimeline(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentURL")) { if (segments == null) { segments = new ArrayList<>(); } segments.add(parseSegmentUrl(xpp)); } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentList")); if (parent != null) { initialization = initialization != null ? initialization : parent.initialization; timeline = timeline != null ? timeline : parent.segmentTimeline; segments = segments != null ? segments : parent.mediaSegments; } return buildSegmentList(initialization, timescale, presentationTimeOffset, startNumber, duration, timeline, segments); }
protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, SegmentTemplate parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", parent != null ? parent.presentationTimeOffset : 0); long duration = parseLong(xpp, "duration", parent != null ? parent.duration : C.TIME_UNSET); int startNumber = parseInt(xpp, "startNumber", parent != null ? parent.startNumber : 1); UrlTemplate mediaTemplate = parseUrlTemplate(xpp, "media", parent != null ? parent.mediaTemplate : null); UrlTemplate initializationTemplate = parseUrlTemplate(xpp, "initialization", parent != null ? parent.initializationTemplate : null); RangedUri initialization = null; List<SegmentTimelineElement> timeline = null; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTimeline")) { timeline = parseSegmentTimeline(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentTemplate")); if (parent != null) { initialization = initialization != null ? initialization : parent.initialization; timeline = timeline != null ? timeline : parent.segmentTimeline; } return buildSegmentTemplate(initialization, timescale, presentationTimeOffset, startNumber, duration, timeline, initializationTemplate, mediaTemplate); }
protected int parseAudioChannelConfiguration(XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeIdUri = parseString(xpp, "schemeIdUri", null); int audioChannels = "urn:mpeg:dash:23003:3:audio_channel_configuration:2011".equals(schemeIdUri) ? parseInt(xpp, "value", Format.NO_VALUE) : Format.NO_VALUE; do { xpp.next(); } while (!XmlPullParserUtil.isEndTag(xpp, "AudioChannelConfiguration")); return audioChannels; }
/** * Parses a {@link SchemeValuePair} from an element. * * @param xpp The parser from which to read. * @param tag The tag of the element being parsed. * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. * @return The parsed {@link SchemeValuePair}. */ protected static SchemeValuePair parseSchemeValuePair(XmlPullParser xpp, String tag) throws XmlPullParserException, IOException { String schemeIdUri = parseString(xpp, "schemeIdUri", null); String value = parseString(xpp, "value", null); do { xpp.next(); } while (!XmlPullParserUtil.isEndTag(xpp, tag)); return new SchemeValuePair(schemeIdUri, value); }
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, baseUrl, null); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, baseUrl, null); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, baseUrl, null); } } while (!XmlPullParserUtil.isEndTag(xpp, "Period")); return Pair.create(buildPeriod(id, startMs, adaptationSets), durationMs); }
/** * Parses a ContentProtection element. * * @param xpp The parser from which to read. * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. * @return {@link SchemeData} parsed from the ContentProtection element, or null if the element is * unsupported. */ protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullParserException, IOException { byte[] data = null; UUID uuid = null; boolean seenPsshElement = false; boolean requiresSecureDecoder = false; do { xpp.next(); // The cenc:pssh element is defined in 23001-7:2015. if (XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) { seenPsshElement = true; data = Base64.decode(xpp.getText(), Base64.DEFAULT); uuid = PsshAtomUtil.parseUuid(data); } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) { String robustnessLevel = xpp.getAttributeValue(null, "robustness_level"); requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW"); } } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection")); if (!seenPsshElement) { return null; } else if (uuid != null) { return new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder); } else { Log.w(TAG, "Skipped unsupported ContentProtection element"); return null; } }
protected SingleSegmentBase parseSegmentBase(XmlPullParser xpp, String baseUrl, SingleSegmentBase parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", parent != null ? parent.presentationTimeOffset : 0); long indexStart = parent != null ? parent.indexStart : 0; long indexLength = parent != null ? parent.indexLength : 0; String indexRangeText = xpp.getAttributeValue(null, "indexRange"); if (indexRangeText != null) { String[] indexRange = indexRangeText.split("-"); indexStart = Long.parseLong(indexRange[0]); indexLength = Long.parseLong(indexRange[1]) - indexStart + 1; } RangedUri initialization = parent != null ? parent.initialization : null; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp, baseUrl); } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentBase")); return buildSingleSegmentBase(initialization, timescale, presentationTimeOffset, baseUrl, indexStart, indexLength); }
protected SegmentList parseSegmentList(XmlPullParser xpp, String baseUrl, SegmentList parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", parent != null ? parent.presentationTimeOffset : 0); long duration = parseLong(xpp, "duration", parent != null ? parent.duration : C.TIME_UNSET); int startNumber = parseInt(xpp, "startNumber", parent != null ? parent.startNumber : 1); RangedUri initialization = null; List<SegmentTimelineElement> timeline = null; List<RangedUri> segments = null; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp, baseUrl); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTimeline")) { timeline = parseSegmentTimeline(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentURL")) { if (segments == null) { segments = new ArrayList<>(); } segments.add(parseSegmentUrl(xpp, baseUrl)); } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentList")); if (parent != null) { initialization = initialization != null ? initialization : parent.initialization; timeline = timeline != null ? timeline : parent.segmentTimeline; segments = segments != null ? segments : parent.mediaSegments; } return buildSegmentList(initialization, timescale, presentationTimeOffset, startNumber, duration, timeline, segments); }
protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, String baseUrl, SegmentTemplate parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); long presentationTimeOffset = parseLong(xpp, "presentationTimeOffset", parent != null ? parent.presentationTimeOffset : 0); long duration = parseLong(xpp, "duration", parent != null ? parent.duration : C.TIME_UNSET); int startNumber = parseInt(xpp, "startNumber", parent != null ? parent.startNumber : 1); UrlTemplate mediaTemplate = parseUrlTemplate(xpp, "media", parent != null ? parent.mediaTemplate : null); UrlTemplate initializationTemplate = parseUrlTemplate(xpp, "initialization", parent != null ? parent.initializationTemplate : null); RangedUri initialization = null; List<SegmentTimelineElement> timeline = null; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp, baseUrl); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTimeline")) { timeline = parseSegmentTimeline(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentTemplate")); if (parent != null) { initialization = initialization != null ? initialization : parent.initialization; timeline = timeline != null ? timeline : parent.segmentTimeline; } return buildSegmentTemplate(initialization, timescale, presentationTimeOffset, startNumber, duration, timeline, initializationTemplate, mediaTemplate, baseUrl); }
/** * Parses a ContentProtection element. * * @param xpp The parser from which to read. * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element. * Either or both may be null, depending on the ContentProtection element being parsed. */ protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeType = null; byte[] data = null; UUID uuid = null; boolean requiresSecureDecoder = false; String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri"); if (schemeIdUri != null) { switch (Util.toLowerInvariant(schemeIdUri)) { case "urn:mpeg:dash:mp4protection:2011": schemeType = xpp.getAttributeValue(null, "value"); String defaultKid = xpp.getAttributeValue(null, "cenc:default_KID"); if (defaultKid != null && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) { UUID keyId = UUID.fromString(defaultKid); data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, new UUID[] {keyId}, null); uuid = C.COMMON_PSSH_UUID; } break; case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95": uuid = C.PLAYREADY_UUID; break; case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed": uuid = C.WIDEVINE_UUID; break; default: break; } } do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) { String robustnessLevel = xpp.getAttributeValue(null, "robustness_level"); requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW"); } else if (data == null) { if (XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) { // The cenc:pssh element is defined in 23001-7:2015. data = Base64.decode(xpp.getText(), Base64.DEFAULT); uuid = PsshAtomUtil.parseUuid(data); if (uuid == null) { Log.w(TAG, "Skipping malformed cenc:pssh data"); data = null; } } else if (uuid == C.PLAYREADY_UUID && XmlPullParserUtil.isStartTag(xpp, "mspr:pro") && xpp.next() == XmlPullParser.TEXT) { // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady. data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID, Base64.decode(xpp.getText(), Base64.DEFAULT)); } } } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection")); SchemeData schemeData = uuid != null ? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder) : null; return Pair.create(schemeType, schemeData); }
protected int parseAudioChannelConfiguration(XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeIdUri = parseString(xpp, "schemeIdUri", null); int audioChannels = "urn:mpeg:dash:23003:3:audio_channel_configuration:2011".equals(schemeIdUri) ? parseInt(xpp, "value", Format.NO_VALUE) : ("tag:dolby.com,2014:dash:audio_channel_configuration:2011".equals(schemeIdUri) ? parseDolbyChannelConfiguration(xpp) : Format.NO_VALUE); do { xpp.next(); } while (!XmlPullParserUtil.isEndTag(xpp, "AudioChannelConfiguration")); return audioChannels; }
/** * Parses a {@link Descriptor} from an element. * * @param xpp The parser from which to read. * @param tag The tag of the element being parsed. * @throws XmlPullParserException If an error occurs parsing the element. * @throws IOException If an error occurs reading the element. * @return The parsed {@link Descriptor}. */ protected static Descriptor parseDescriptor(XmlPullParser xpp, String tag) throws XmlPullParserException, IOException { String schemeIdUri = parseString(xpp, "schemeIdUri", ""); String value = parseString(xpp, "value", null); String id = parseString(xpp, "id", null); do { xpp.next(); } while (!XmlPullParserUtil.isEndTag(xpp, tag)); return new Descriptor(schemeIdUri, value, id); }
protected DashManifest parseMediaPresentationDescription(XmlPullParser xpp, String baseUrl) throws XmlPullParserException, IOException { long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", C.TIME_UNSET); long durationMs = parseDuration(xpp, "mediaPresentationDuration", C.TIME_UNSET); long minBufferTimeMs = parseDuration(xpp, "minBufferTime", C.TIME_UNSET); String typeString = xpp.getAttributeValue(null, "type"); boolean dynamic = typeString != null && typeString.equals("dynamic"); long minUpdateTimeMs = dynamic ? parseDuration(xpp, "minimumUpdatePeriod", C.TIME_UNSET) : C.TIME_UNSET; long timeShiftBufferDepthMs = dynamic ? parseDuration(xpp, "timeShiftBufferDepth", C.TIME_UNSET) : C.TIME_UNSET; long suggestedPresentationDelayMs = dynamic ? parseDuration(xpp, "suggestedPresentationDelay", C.TIME_UNSET) : C.TIME_UNSET; UtcTimingElement utcTiming = null; Uri location = null; List<Period> periods = new ArrayList<>(); long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0; boolean seenEarlyAccessPeriod = false; boolean seenFirstBaseUrl = false; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } } else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) { utcTiming = parseUtcTiming(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { location = Uri.parse(xpp.nextText()); } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { Pair<Period, Long> periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs); Period period = periodWithDurationMs.first; if (period.startMs == C.TIME_UNSET) { if (dynamic) { // This is an early access period. Ignore it. All subsequent periods must also be // early access. seenEarlyAccessPeriod = true; } else { throw new ParserException("Unable to determine start of period " + periods.size()); } } else { long periodDurationMs = periodWithDurationMs.second; nextPeriodStartMs = periodDurationMs == C.TIME_UNSET ? C.TIME_UNSET : (period.startMs + periodDurationMs); periods.add(period); } } } while (!XmlPullParserUtil.isEndTag(xpp, "MPD")); if (durationMs == C.TIME_UNSET) { if (nextPeriodStartMs != C.TIME_UNSET) { // If we know the end time of the final period, we can use it as the duration. durationMs = nextPeriodStartMs; } else if (!dynamic) { throw new ParserException("Unable to determine duration of static manifest."); } } if (periods.isEmpty()) { throw new ParserException("No periods found."); } return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, utcTiming, location, periods); }
protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl, SegmentBase segmentBase) throws XmlPullParserException, IOException { int id = parseInt(xpp, "id", AdaptationSet.ID_UNSET); int contentType = parseContentType(xpp); String mimeType = xpp.getAttributeValue(null, "mimeType"); String codecs = xpp.getAttributeValue(null, "codecs"); int width = parseInt(xpp, "width", Format.NO_VALUE); int height = parseInt(xpp, "height", Format.NO_VALUE); float frameRate = parseFrameRate(xpp, Format.NO_VALUE); int audioChannels = Format.NO_VALUE; int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE); String language = xpp.getAttributeValue(null, "lang"); ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>(); ArrayList<SchemeValuePair> inbandEventStreams = new ArrayList<>(); ArrayList<SchemeValuePair> accessibilityDescriptors = new ArrayList<>(); List<RepresentationInfo> representationInfos = new ArrayList<>(); @C.SelectionFlags int selectionFlags = 0; boolean seenFirstBaseUrl = false; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { SchemeData contentProtection = parseContentProtection(xpp); if (contentProtection != null) { drmSchemeDatas.add(contentProtection); } } else if (XmlPullParserUtil.isStartTag(xpp, "ContentComponent")) { language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang")); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Role")) { selectionFlags |= parseRole(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) { accessibilityDescriptors.add(parseAccessibility(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, width, height, frameRate, audioChannels, audioSamplingRate, language, selectionFlags, accessibilityDescriptors, segmentBase); contentType = checkContentTypeConsistency(contentType, getContentType(representationInfo.format)); representationInfos.add(representationInfo); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) { inbandEventStreams.add(parseInbandEventStream(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp)) { parseAdaptationSetChild(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet")); // Build the representations. List<Representation> representations = new ArrayList<>(representationInfos.size()); for (int i = 0; i < representationInfos.size(); i++) { representations.add(buildRepresentation(representationInfos.get(i), contentId, drmSchemeDatas, inbandEventStreams)); } return buildAdaptationSet(id, contentType, representations, accessibilityDescriptors); }
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl, String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, String adaptationSetLanguage, @C.SelectionFlags int adaptationSetSelectionFlags, List<SchemeValuePair> adaptationSetAccessibilityDescriptors, SegmentBase segmentBase) 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); ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>(); ArrayList<SchemeValuePair> inbandEventStreams = 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, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { SchemeData contentProtection = parseContentProtection(xpp); if (contentProtection != null) { drmSchemeDatas.add(contentProtection); } } else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) { inbandEventStreams.add(parseInbandEventStream(xpp)); } } while (!XmlPullParserUtil.isEndTag(xpp, "Representation")); Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetSelectionFlags, adaptationSetAccessibilityDescriptors, codecs); segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(); return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas, inbandEventStreams); }
protected DashManifest parseMediaPresentationDescription(XmlPullParser xpp, String baseUrl) throws XmlPullParserException, IOException, ParseException { long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", C.TIME_UNSET); long durationMs = parseDuration(xpp, "mediaPresentationDuration", C.TIME_UNSET); long minBufferTimeMs = parseDuration(xpp, "minBufferTime", C.TIME_UNSET); String typeString = xpp.getAttributeValue(null, "type"); boolean dynamic = typeString != null && typeString.equals("dynamic"); long minUpdateTimeMs = dynamic ? parseDuration(xpp, "minimumUpdatePeriod", C.TIME_UNSET) : C.TIME_UNSET; long timeShiftBufferDepthMs = dynamic ? parseDuration(xpp, "timeShiftBufferDepth", C.TIME_UNSET) : C.TIME_UNSET; long suggestedPresentationDelayMs = dynamic ? parseDuration(xpp, "suggestedPresentationDelay", C.TIME_UNSET) : C.TIME_UNSET; UtcTimingElement utcTiming = null; Uri location = null; List<Period> periods = new ArrayList<>(); long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0; boolean seenEarlyAccessPeriod = false; boolean seenFirstBaseUrl = false; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } } else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) { utcTiming = parseUtcTiming(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { location = Uri.parse(xpp.nextText()); } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { Pair<Period, Long> periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs); Period period = periodWithDurationMs.first; if (period.startMs == C.TIME_UNSET) { if (dynamic) { // This is an early access period. Ignore it. All subsequent periods must also be // early access. seenEarlyAccessPeriod = true; } else { throw new ParserException("Unable to determine start of period " + periods.size()); } } else { long periodDurationMs = periodWithDurationMs.second; nextPeriodStartMs = periodDurationMs == C.TIME_UNSET ? C.TIME_UNSET : (period.startMs + periodDurationMs); periods.add(period); } } } while (!XmlPullParserUtil.isEndTag(xpp, "MPD")); if (durationMs == C.TIME_UNSET) { if (nextPeriodStartMs != C.TIME_UNSET) { // If we know the end time of the final period, we can use it as the duration. durationMs = nextPeriodStartMs; } else if (!dynamic) { throw new ParserException("Unable to determine duration of static manifest."); } } if (periods.isEmpty()) { throw new ParserException("No periods found."); } return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, utcTiming, location, periods); }
protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl, SegmentBase segmentBase) throws XmlPullParserException, IOException { int id = parseInt(xpp, "id", AdaptationSet.UNSET_ID); int contentType = parseContentType(xpp); String mimeType = xpp.getAttributeValue(null, "mimeType"); String codecs = xpp.getAttributeValue(null, "codecs"); int width = parseInt(xpp, "width", Format.NO_VALUE); int height = parseInt(xpp, "height", Format.NO_VALUE); float frameRate = parseFrameRate(xpp, Format.NO_VALUE); int audioChannels = Format.NO_VALUE; int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE); String language = xpp.getAttributeValue(null, "lang"); ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>(); List<RepresentationInfo> representationInfos = 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, "ContentProtection")) { SchemeData contentProtection = parseContentProtection(xpp); if (contentProtection != null) { drmSchemeDatas.add(contentProtection); } } else if (XmlPullParserUtil.isStartTag(xpp, "ContentComponent")) { language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang")); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, width, height, frameRate, audioChannels, audioSamplingRate, language, segmentBase); contentType = checkContentTypeConsistency(contentType, getContentType(representationInfo.format)); representationInfos.add(representationInfo); } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, baseUrl, (SingleSegmentBase) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, baseUrl, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, baseUrl, (SegmentTemplate) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp)) { parseAdaptationSetChild(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet")); List<Representation> representations = new ArrayList<>(representationInfos.size()); for (int i = 0; i < representationInfos.size(); i++) { representations.add(buildRepresentation(representationInfos.get(i), contentId, drmSchemeDatas)); } return buildAdaptationSet(id, contentType, representations); }
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl, String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, String adaptationSetLanguage, SegmentBase segmentBase) 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); ArrayList<SchemeData> drmSchemeDatas = 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, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, baseUrl, (SingleSegmentBase) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, baseUrl, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, baseUrl, (SegmentTemplate) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { SchemeData contentProtection = parseContentProtection(xpp); if (contentProtection != null) { drmSchemeDatas.add(contentProtection); } } } while (!XmlPullParserUtil.isEndTag(xpp, "Representation")); Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, codecs); segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(baseUrl); return new RepresentationInfo(format, segmentBase, drmSchemeDatas); }
protected DashManifest parseMediaPresentationDescription(XmlPullParser xpp, String baseUrl) throws XmlPullParserException, IOException { long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", C.TIME_UNSET); long durationMs = parseDuration(xpp, "mediaPresentationDuration", C.TIME_UNSET); long minBufferTimeMs = parseDuration(xpp, "minBufferTime", C.TIME_UNSET); String typeString = xpp.getAttributeValue(null, "type"); boolean dynamic = typeString != null && typeString.equals("dynamic"); long minUpdateTimeMs = dynamic ? parseDuration(xpp, "minimumUpdatePeriod", C.TIME_UNSET) : C.TIME_UNSET; long timeShiftBufferDepthMs = dynamic ? parseDuration(xpp, "timeShiftBufferDepth", C.TIME_UNSET) : C.TIME_UNSET; long suggestedPresentationDelayMs = dynamic ? parseDuration(xpp, "suggestedPresentationDelay", C.TIME_UNSET) : C.TIME_UNSET; long publishTimeMs = parseDateTime(xpp, "publishTime", C.TIME_UNSET); UtcTimingElement utcTiming = null; Uri location = null; List<Period> periods = new ArrayList<>(); long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0; boolean seenEarlyAccessPeriod = false; boolean seenFirstBaseUrl = false; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } } else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) { utcTiming = parseUtcTiming(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { location = Uri.parse(xpp.nextText()); } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { Pair<Period, Long> periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs); Period period = periodWithDurationMs.first; if (period.startMs == C.TIME_UNSET) { if (dynamic) { // This is an early access period. Ignore it. All subsequent periods must also be // early access. seenEarlyAccessPeriod = true; } else { throw new ParserException("Unable to determine start of period " + periods.size()); } } else { long periodDurationMs = periodWithDurationMs.second; nextPeriodStartMs = periodDurationMs == C.TIME_UNSET ? C.TIME_UNSET : (period.startMs + periodDurationMs); periods.add(period); } } } while (!XmlPullParserUtil.isEndTag(xpp, "MPD")); if (durationMs == C.TIME_UNSET) { if (nextPeriodStartMs != C.TIME_UNSET) { // If we know the end time of the final period, we can use it as the duration. durationMs = nextPeriodStartMs; } else if (!dynamic) { throw new ParserException("Unable to determine duration of static manifest."); } } if (periods.isEmpty()) { throw new ParserException("No periods found."); } return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, publishTimeMs, utcTiming, location, periods); }
protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl, SegmentBase segmentBase) throws XmlPullParserException, IOException { int id = parseInt(xpp, "id", AdaptationSet.ID_UNSET); int contentType = parseContentType(xpp); String mimeType = xpp.getAttributeValue(null, "mimeType"); String codecs = xpp.getAttributeValue(null, "codecs"); int width = parseInt(xpp, "width", Format.NO_VALUE); int height = parseInt(xpp, "height", Format.NO_VALUE); float frameRate = parseFrameRate(xpp, Format.NO_VALUE); int audioChannels = Format.NO_VALUE; int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE); String language = xpp.getAttributeValue(null, "lang"); String drmSchemeType = null; ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>(); ArrayList<Descriptor> inbandEventStreams = new ArrayList<>(); ArrayList<Descriptor> accessibilityDescriptors = new ArrayList<>(); ArrayList<Descriptor> supplementalProperties = new ArrayList<>(); List<RepresentationInfo> representationInfos = new ArrayList<>(); @C.SelectionFlags int selectionFlags = 0; boolean seenFirstBaseUrl = false; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } } 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, "ContentComponent")) { language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang")); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Role")) { selectionFlags |= parseRole(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) { accessibilityDescriptors.add(parseDescriptor(xpp, "Accessibility")); } else if (XmlPullParserUtil.isStartTag(xpp, "SupplementalProperty")) { supplementalProperties.add(parseDescriptor(xpp, "SupplementalProperty")); } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, width, height, frameRate, audioChannels, audioSamplingRate, language, selectionFlags, accessibilityDescriptors, segmentBase); contentType = checkContentTypeConsistency(contentType, getContentType(representationInfo.format)); representationInfos.add(representationInfo); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) { inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream")); } else if (XmlPullParserUtil.isStartTag(xpp)) { parseAdaptationSetChild(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet")); // Build the representations. List<Representation> representations = new ArrayList<>(representationInfos.size()); for (int i = 0; i < representationInfos.size(); i++) { representations.add(buildRepresentation(representationInfos.get(i), contentId, drmSchemeType, drmSchemeDatas, inbandEventStreams)); } return buildAdaptationSet(id, contentType, representations, accessibilityDescriptors, supplementalProperties); }
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl, String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, String adaptationSetLanguage, @C.SelectionFlags int adaptationSetSelectionFlags, List<Descriptor> adaptationSetAccessibilityDescriptors, SegmentBase segmentBase) 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> supplementalProperties = 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, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase); } 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, "SupplementalProperty")) { supplementalProperties.add(parseDescriptor(xpp, "SupplementalProperty")); } } while (!XmlPullParserUtil.isEndTag(xpp, "Representation")); Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetSelectionFlags, adaptationSetAccessibilityDescriptors, codecs, supplementalProperties); segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(); return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeType, drmSchemeDatas, inbandEventStreams, Representation.REVISION_ID_DEFAULT); }