Parse some DASH manifest components for DVB LIVE.

This commit is contained in:
Oliver Woodman 2014-09-08 11:23:35 +01:00
parent 5d35698d8f
commit 1ddd5c6e16
6 changed files with 95 additions and 35 deletions

View file

@ -23,6 +23,8 @@ import java.util.List;
*/
public final class MediaPresentationDescription {
public final long availabilityStartTime;
public final long duration;
public final long minBufferTime;
@ -31,14 +33,22 @@ public final class MediaPresentationDescription {
public final long minUpdatePeriod;
public final long timeShiftBufferDepth;
public final List<Period> periods;
public MediaPresentationDescription(long duration, long minBufferTime, boolean dynamic,
long minUpdatePeriod, List<Period> periods) {
public final UtcTimingElement utcTiming;
public MediaPresentationDescription(long availabilityStartTime, long duration, long minBufferTime,
boolean dynamic, long minUpdatePeriod, long timeShiftBufferDepth, UtcTimingElement utcTiming,
List<Period> periods) {
this.availabilityStartTime = availabilityStartTime;
this.duration = duration;
this.minBufferTime = minBufferTime;
this.dynamic = dynamic;
this.minUpdatePeriod = minUpdatePeriod;
this.timeShiftBufferDepth = timeShiftBufferDepth;
this.utcTiming = utcTiming;
this.periods = Collections.unmodifiableList(periods);
}

View file

@ -20,8 +20,6 @@ import com.google.android.exoplayer.util.ManifestFetcher;
import android.net.Uri;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
@ -60,11 +58,7 @@ public final class MediaPresentationDescriptionFetcher extends
@Override
protected MediaPresentationDescription parse(InputStream stream, String inputEncoding,
String contentId, Uri baseUrl) throws IOException, ParserException {
try {
return parser.parseMediaPresentationDescription(stream, inputEncoding, contentId, baseUrl);
} catch (XmlPullParserException e) {
throw new ParserException(e);
}
return parser.parseMediaPresentationDescription(stream, inputEncoding, contentId, baseUrl);
}
}

View file

@ -34,8 +34,11 @@ import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -69,42 +72,57 @@ public class MediaPresentationDescriptionParser extends DefaultHandler {
* @param baseUrl The url that any relative urls defined within the manifest are relative to.
* @return The parsed manifest.
* @throws IOException If a problem occurred reading from the stream.
* @throws XmlPullParserException If a problem occurred parsing the stream as xml.
* @throws ParserException If a problem occurred parsing the xml as a DASH mpd.
*/
public MediaPresentationDescription parseMediaPresentationDescription(InputStream inputStream,
String inputEncoding, String contentId, Uri baseUrl) throws XmlPullParserException,
IOException, ParserException {
XmlPullParser xpp = xmlParserFactory.newPullParser();
xpp.setInput(inputStream, inputEncoding);
int eventType = xpp.next();
if (eventType != XmlPullParser.START_TAG || !"MPD".equals(xpp.getName())) {
throw new ParserException(
"inputStream does not contain a valid media presentation description");
String inputEncoding, String contentId, Uri baseUrl) throws IOException, ParserException {
try {
XmlPullParser xpp = xmlParserFactory.newPullParser();
xpp.setInput(inputStream, inputEncoding);
int eventType = xpp.next();
if (eventType != XmlPullParser.START_TAG || !"MPD".equals(xpp.getName())) {
throw new ParserException(
"inputStream does not contain a valid media presentation description");
}
return parseMediaPresentationDescription(xpp, contentId, baseUrl);
} catch (XmlPullParserException e) {
throw new ParserException(e);
} catch (ParseException e) {
throw new ParserException(e);
}
return parseMediaPresentationDescription(xpp, contentId, baseUrl);
}
private MediaPresentationDescription parseMediaPresentationDescription(XmlPullParser xpp,
String contentId, Uri baseUrl) throws XmlPullParserException, IOException {
String contentId, Uri baseUrl) throws XmlPullParserException, IOException, ParseException {
long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", -1);
long durationMs = parseDurationMs(xpp, "mediaPresentationDuration");
long minBufferTimeMs = parseDurationMs(xpp, "minBufferTime");
String typeString = xpp.getAttributeValue(null, "type");
boolean dynamic = (typeString != null) ? typeString.equals("dynamic") : false;
long minUpdateTimeMs = (dynamic) ? parseDurationMs(xpp, "minimumUpdatePeriod", -1) : -1;
long timeShiftBufferDepthMs = (dynamic) ? parseDurationMs(xpp, "timeShiftBufferDepth", -1) : -1;
UtcTimingElement utcTiming = null;
List<Period> periods = new ArrayList<Period>();
do {
xpp.next();
if (isStartTag(xpp, "BaseURL")) {
baseUrl = parseBaseUrl(xpp, baseUrl);
} else if (isStartTag(xpp, "UTCTiming")) {
utcTiming = parseUtcTiming(xpp);
} else if (isStartTag(xpp, "Period")) {
periods.add(parsePeriod(xpp, contentId, baseUrl, durationMs));
}
} while (!isEndTag(xpp, "MPD"));
return new MediaPresentationDescription(durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs,
periods);
return new MediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, periods);
}
private UtcTimingElement parseUtcTiming(XmlPullParser xpp) {
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
String value = xpp.getAttributeValue(null, "value");
return new UtcTimingElement(schemeIdUri, value);
}
private Period parsePeriod(XmlPullParser xpp, String contentId, Uri baseUrl, long mpdDurationMs)
@ -429,6 +447,16 @@ public class MediaPresentationDescriptionParser extends DefaultHandler {
return parseDurationMs(xpp, name, -1);
}
private static long parseDateTime(XmlPullParser xpp, String name, long defaultValue)
throws ParseException {
String value = xpp.getAttributeValue(null, name);
if (value != null) {
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss'Z'", Locale.US);
return parser.parse(value).getTime();
}
return defaultValue;
}
private static long parseDurationMs(XmlPullParser xpp, String name, long defaultValue) {
String value = xpp.getAttributeValue(null, name);
if (value != null) {

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer.dash.mpd;
/**
* Represents a UTCTiming element.
*/
public class UtcTimingElement {
public final String schemeIdUri;
public final String value;
public UtcTimingElement(String schemeIdUri, String value) {
this.schemeIdUri = schemeIdUri;
this.value = value;
}
}

View file

@ -20,8 +20,6 @@ import com.google.android.exoplayer.util.ManifestFetcher;
import android.net.Uri;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
@ -59,11 +57,7 @@ public final class SmoothStreamingManifestFetcher extends ManifestFetcher<Smooth
@Override
protected SmoothStreamingManifest parse(InputStream stream, String inputEncoding,
String contentId, Uri baseUrl) throws IOException, ParserException {
try {
return parser.parse(stream, inputEncoding);
} catch (XmlPullParserException e) {
throw new ParserException(e);
}
return parser.parse(stream, inputEncoding);
}
}

View file

@ -60,15 +60,18 @@ public class SmoothStreamingManifestParser {
* @param inputEncoding The encoding of the input.
* @return The parsed manifest.
* @throws IOException If a problem occurred reading from the stream.
* @throws XmlPullParserException If a problem occurred parsing the stream as xml.
* @throws ParserException If a problem occurred parsing the xml as a smooth streaming manifest.
*/
public SmoothStreamingManifest parse(InputStream inputStream, String inputEncoding) throws
XmlPullParserException, IOException, ParserException {
XmlPullParser xmlParser = xmlParserFactory.newPullParser();
xmlParser.setInput(inputStream, inputEncoding);
SmoothStreamMediaParser smoothStreamMediaParser = new SmoothStreamMediaParser(null);
return (SmoothStreamingManifest) smoothStreamMediaParser.parse(xmlParser);
IOException, ParserException {
try {
XmlPullParser xmlParser = xmlParserFactory.newPullParser();
xmlParser.setInput(inputStream, inputEncoding);
SmoothStreamMediaParser smoothStreamMediaParser = new SmoothStreamMediaParser(null);
return (SmoothStreamingManifest) smoothStreamMediaParser.parse(xmlParser);
} catch (XmlPullParserException e) {
throw new ParserException(e);
}
}
/**