&subtitle.",
subtitle.getCues(subtitle.getEventTime(6)).get(0).text.toString());
- assertEquals(startTimeUs + 7000000, subtitle.getEventTime(7));
+ assertEquals(7000000, subtitle.getEventTime(7));
}
public void testParseLiveTypicalWebvttFile() throws IOException {
diff --git a/library/src/main/java/com/google/android/exoplayer/C.java b/library/src/main/java/com/google/android/exoplayer/C.java
index af6e619a6d..145e151099 100644
--- a/library/src/main/java/com/google/android/exoplayer/C.java
+++ b/library/src/main/java/com/google/android/exoplayer/C.java
@@ -90,18 +90,6 @@ public final class C {
*/
public static final int RESULT_END_OF_INPUT = -1;
- /**
- * A prefix for custom ExoPlayer WebVTT headers.
- */
- public static final String WEBVTT_EXO_HEADER = "EXO-HEADER";
-
- /**
- * An element of a custom ExoPlayer WebVTT header. An {@code WEBVTT_OFFSET + value} element can
- * be added to a custom ExoPlayer WebVTT header to specify an offset time (in microseconds) that
- * should be added to the embedded MPEGTS value.
- */
- public static final String WEBVTT_EXO_HEADER_OFFSET = "OFFSET:";
-
private C() {}
}
diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
index 12f7689099..1068e1699a 100644
--- a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
+++ b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java
@@ -109,7 +109,7 @@ public final class SingleSampleChunkSource implements ChunkSource {
private SingleSampleMediaChunk initChunk() {
return new SingleSampleMediaChunk(dataSource, dataSpec, Chunk.TRIGGER_UNSPECIFIED, format, 0,
- durationUs, 0, true, mediaFormat, null, null);
+ durationUs, 0, true, mediaFormat, null);
}
}
diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java
index de2c7067cc..064638580b 100644
--- a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java
+++ b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleMediaChunk.java
@@ -20,7 +20,6 @@ import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.drm.DrmInitData;
import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer.upstream.DataSpec;
-import com.google.android.exoplayer.util.ParsableByteArray;
import com.google.android.exoplayer.util.Util;
import java.io.IOException;
@@ -32,9 +31,6 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
private final MediaFormat sampleFormat;
private final DrmInitData sampleDrmInitData;
- private final byte[] headerData;
-
- private boolean writtenHeader;
private volatile int bytesLoaded;
private volatile boolean loadCanceled;
@@ -51,18 +47,14 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
* @param sampleFormat The format of the sample.
* @param sampleDrmInitData The {@link DrmInitData} for the sample. Null if the sample is not drm
* protected.
- * @param headerData Custom header data for the sample. May be null. If set, the header data is
- * prepended to the sample data. It is not reflected in the values returned by
- * {@link #bytesLoaded()}.
*/
public SingleSampleMediaChunk(DataSource dataSource, DataSpec dataSpec, int trigger,
Format format, long startTimeUs, long endTimeUs, int chunkIndex, boolean isLastChunk,
- MediaFormat sampleFormat, DrmInitData sampleDrmInitData, byte[] headerData) {
+ MediaFormat sampleFormat, DrmInitData sampleDrmInitData) {
super(dataSource, dataSpec, trigger, format, startTimeUs, endTimeUs, chunkIndex, isLastChunk,
true);
this.sampleFormat = sampleFormat;
this.sampleDrmInitData = sampleDrmInitData;
- this.headerData = headerData;
}
@Override
@@ -95,13 +87,6 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
@SuppressWarnings("NonAtomicVolatileUpdate")
@Override
public void load() throws IOException, InterruptedException {
- if (!writtenHeader) {
- if (headerData != null) {
- getOutput().sampleData(new ParsableByteArray(headerData), headerData.length);
- }
- writtenHeader = true;
- }
-
DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded);
try {
// Create and open the input.
@@ -113,9 +98,6 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
result = getOutput().sampleData(dataSource, Integer.MAX_VALUE, true);
}
int sampleSize = bytesLoaded;
- if (headerData != null) {
- sampleSize += headerData.length;
- }
getOutput().sampleMetadata(startTimeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
} finally {
dataSource.close();
diff --git a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
index 815f4c02dd..eb1b096947 100644
--- a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
+++ b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java
@@ -16,7 +16,6 @@
package com.google.android.exoplayer.dash;
import com.google.android.exoplayer.BehindLiveWindowException;
-import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.TimeRange;
import com.google.android.exoplayer.TrackInfo;
@@ -104,7 +103,6 @@ public class DashChunkSource implements ChunkSource {
private final FormatEvaluator formatEvaluator;
private final Evaluation evaluation;
private final Clock systemClock;
- private final StringBuilder headerBuilder;
private final long liveEdgeLatencyUs;
private final long elapsedRealtimeOffsetUs;
private final int maxWidth;
@@ -258,7 +256,6 @@ public class DashChunkSource implements ChunkSource {
this.eventHandler = eventHandler;
this.eventListener = eventListener;
this.evaluation = new Evaluation();
- this.headerBuilder = new StringBuilder();
this.seekRangeValues = new long[2];
drmInitData = getDrmInitData(currentManifest, adaptationSetIndex);
@@ -645,19 +642,9 @@ public class DashChunkSource implements ChunkSource {
long sampleOffsetUs = representation.periodStartMs * 1000
- representation.presentationTimeOffsetUs;
if (representation.format.mimeType.equals(MimeTypes.TEXT_VTT)) {
- if (representationHolder.vttHeaderOffsetUs != sampleOffsetUs) {
- // Update the VTT header.
- headerBuilder.setLength(0);
- headerBuilder.append(C.WEBVTT_EXO_HEADER).append("=")
- .append(C.WEBVTT_EXO_HEADER_OFFSET).append(sampleOffsetUs)
- .append("\n");
- representationHolder.vttHeader = headerBuilder.toString().getBytes();
- representationHolder.vttHeaderOffsetUs = sampleOffsetUs;
- }
return new SingleSampleMediaChunk(dataSource, dataSpec, Chunk.TRIGGER_INITIAL,
representation.format, startTimeUs, endTimeUs, absoluteSegmentNum, isLastSegment,
- MediaFormat.createTextFormat(MimeTypes.TEXT_VTT, representation.format.language), null,
- representationHolder.vttHeader);
+ MediaFormat.createTextFormat(MimeTypes.TEXT_VTT, representation.format.language), null);
} else {
return new ContainerMediaChunk(dataSource, dataSpec, trigger, representation.format,
startTimeUs, endTimeUs, absoluteSegmentNum, isLastSegment, sampleOffsetUs,
@@ -741,8 +728,6 @@ public class DashChunkSource implements ChunkSource {
public MediaFormat format;
public int segmentNumShift;
- public long vttHeaderOffsetUs;
- public byte[] vttHeader;
public RepresentationHolder(Representation representation,
ChunkExtractorWrapper extractorWrapper) {
diff --git a/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java b/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java
index bebf643e82..091f8150f6 100644
--- a/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java
+++ b/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java
@@ -38,12 +38,10 @@ import java.util.regex.Pattern;
*
* @see WebVTT specification
*/
-public class WebvttParser implements SubtitleParser {
+public final class WebvttParser implements SubtitleParser {
private static final String TAG = "WebvttParser";
- private static final long SAMPLING_RATE = 90;
-
private static final String WEBVTT_FILE_HEADER_STRING = "^\uFEFF?WEBVTT((\\u0020|\u0009).*)?$";
private static final Pattern WEBVTT_FILE_HEADER =
Pattern.compile(WEBVTT_FILE_HEADER_STRING);
@@ -62,10 +60,6 @@ public class WebvttParser implements SubtitleParser {
private static final String WEBVTT_CUE_SETTING_STRING = "\\S*:\\S*";
private static final Pattern WEBVTT_CUE_SETTING = Pattern.compile(WEBVTT_CUE_SETTING_STRING);
- private static final Pattern MEDIA_TIMESTAMP_OFFSET =
- Pattern.compile(C.WEBVTT_EXO_HEADER_OFFSET + "\\-?\\d+");
- private static final Pattern MEDIA_TIMESTAMP = Pattern.compile("MPEGTS:\\d+");
-
private static final String NON_NUMERIC_STRING = ".*[^0-9].*";
private final StringBuilder textBuilder;
@@ -94,33 +88,13 @@ public class WebvttParser implements SubtitleParser {
public final WebvttSubtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs)
throws IOException {
ArrayList subtitles = new ArrayList<>();
- long mediaTimestampUs = startTimeUs;
- long mediaTimestampOffsetUs = 0;
BufferedReader webvttData = new BufferedReader(new InputStreamReader(inputStream, C.UTF8_NAME));
String line;
- // file should start with "WEBVTT" on the first line or "EXO-HEADER"
+ // file should start with "WEBVTT"
line = webvttData.readLine();
- if (line == null) {
- throw new ParserException("Expected WEBVTT or EXO-HEADER. Got null");
- }
-
- if (line.startsWith(C.WEBVTT_EXO_HEADER)) {
- // parse the timestamp offset, if present
- Matcher matcher = MEDIA_TIMESTAMP_OFFSET.matcher(line);
- if (matcher.find()) {
- mediaTimestampOffsetUs = Long.parseLong(matcher.group().substring(7));
- }
-
- // read the next line, which should now be WEBVTT
- line = webvttData.readLine();
- if (line == null) {
- throw new ParserException("Expected WEBVTT. Got null");
- }
- }
-
- if (!WEBVTT_FILE_HEADER.matcher(line).matches()) {
+ if (line == null || !WEBVTT_FILE_HEADER.matcher(line).matches()) {
throw new ParserException("Expected WEBVTT. Got " + line);
}
@@ -135,21 +109,11 @@ public class WebvttParser implements SubtitleParser {
break;
}
- Matcher matcher = WEBVTT_METADATA_HEADER.matcher(line);
- if (!matcher.find()) {
- handleNoncompliantLine(line);
- }
-
- if (line.startsWith("X-TIMESTAMP-MAP")) {
- // parse the media timestamp
- Matcher timestampMatcher = MEDIA_TIMESTAMP.matcher(line);
- if (!timestampMatcher.find()) {
- throw new ParserException("X-TIMESTAMP-MAP doesn't contain media timestamp: " + line);
- } else {
- mediaTimestampUs = (Long.parseLong(timestampMatcher.group().substring(7)) * 1000)
- / SAMPLING_RATE + mediaTimestampOffsetUs;
+ if (strictParsing) {
+ Matcher matcher = WEBVTT_METADATA_HEADER.matcher(line);
+ if (!matcher.find()) {
+ throw new ParserException("Unexpected line: " + line);
}
- mediaTimestampUs = getAdjustedStartTime(mediaTimestampUs);
}
}
@@ -178,7 +142,7 @@ public class WebvttParser implements SubtitleParser {
if (!matcher.find()) {
throw new ParserException("Expected cue start time: " + line);
} else {
- startTime = parseTimestampUs(matcher.group()) + mediaTimestampUs;
+ startTime = parseTimestampUs(matcher.group()) + startTimeUs;
}
// parse end timestamp
@@ -187,7 +151,7 @@ public class WebvttParser implements SubtitleParser {
throw new ParserException("Expected cue end time: " + line);
} else {
endTimeString = matcher.group();
- endTime = parseTimestampUs(endTimeString) + mediaTimestampUs;
+ endTime = parseTimestampUs(endTimeString) + startTimeUs;
}
// parse the (optional) cue setting list
@@ -249,7 +213,7 @@ public class WebvttParser implements SubtitleParser {
subtitles.add(cue);
}
- return new WebvttSubtitle(subtitles, mediaTimestampUs);
+ return new WebvttSubtitle(subtitles, startTimeUs);
}
@Override
@@ -257,16 +221,6 @@ public class WebvttParser implements SubtitleParser {
return MimeTypes.TEXT_VTT.equals(mimeType);
}
- protected long getAdjustedStartTime(long startTimeUs) {
- return startTimeUs;
- }
-
- protected void handleNoncompliantLine(String line) throws ParserException {
- if (strictParsing) {
- throw new ParserException("Unexpected line: " + line);
- }
- }
-
private static int parseIntPercentage(String s) throws NumberFormatException {
if (!s.endsWith("%")) {
throw new NumberFormatException(s + " doesn't end with '%'");