Expose cue settings parser
This CL exposes the cue settings parser in order to allow its usage from the MP4Webvtt extractor. Also fixes a few mistakes from the previous related CL. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=112145806
This commit is contained in:
parent
6b9a1b16f1
commit
b6b97a8683
@ -18,6 +18,7 @@ package com.google.android.exoplayer.text.webvtt;
|
|||||||
import com.google.android.exoplayer.text.Cue;
|
import com.google.android.exoplayer.text.Cue;
|
||||||
|
|
||||||
import android.text.Layout.Alignment;
|
import android.text.Layout.Alignment;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a WebVTT cue.
|
* A representation of a WebVTT cue.
|
||||||
@ -53,4 +54,127 @@ import android.text.Layout.Alignment;
|
|||||||
return (line == DIMEN_UNSET && position == DIMEN_UNSET);
|
return (line == DIMEN_UNSET && position == DIMEN_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for WebVTT cues.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("hiding")
|
||||||
|
public static final class Builder {
|
||||||
|
|
||||||
|
private static final String TAG = "WebvttCueBuilder";
|
||||||
|
|
||||||
|
private long startTime;
|
||||||
|
private long endTime;
|
||||||
|
private CharSequence text;
|
||||||
|
private Alignment textAlignment;
|
||||||
|
private float line;
|
||||||
|
private int lineType;
|
||||||
|
private int lineAnchor;
|
||||||
|
private float position;
|
||||||
|
private int positionAnchor;
|
||||||
|
private float width;
|
||||||
|
|
||||||
|
// Initialization methods
|
||||||
|
|
||||||
|
public Builder() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
startTime = 0;
|
||||||
|
endTime = 0;
|
||||||
|
text = null;
|
||||||
|
textAlignment = null;
|
||||||
|
line = Cue.DIMEN_UNSET;
|
||||||
|
lineType = Cue.TYPE_UNSET;
|
||||||
|
lineAnchor = Cue.TYPE_UNSET;
|
||||||
|
position = Cue.DIMEN_UNSET;
|
||||||
|
positionAnchor = Cue.TYPE_UNSET;
|
||||||
|
width = Cue.DIMEN_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construction methods
|
||||||
|
|
||||||
|
public WebvttCue build() {
|
||||||
|
if (position != Cue.DIMEN_UNSET && positionAnchor == Cue.TYPE_UNSET) {
|
||||||
|
derivePositionAnchorFromAlignment();
|
||||||
|
}
|
||||||
|
return new WebvttCue(startTime, endTime, text, textAlignment, line, lineType, lineAnchor,
|
||||||
|
position, positionAnchor, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setStartTime(long time) {
|
||||||
|
startTime = time;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setEndTime(long time) {
|
||||||
|
endTime = time;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setText(CharSequence aText) {
|
||||||
|
text = aText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setTextAlignment(Alignment textAlignment) {
|
||||||
|
this.textAlignment = textAlignment;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setLine(float line) {
|
||||||
|
this.line = line;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setLineType(int lineType) {
|
||||||
|
this.lineType = lineType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setLineAnchor(int lineAnchor) {
|
||||||
|
this.lineAnchor = lineAnchor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setPosition(float position) {
|
||||||
|
this.position = position;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setPositionAnchor(int positionAnchor) {
|
||||||
|
this.positionAnchor = positionAnchor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setWidth(float width) {
|
||||||
|
this.width = width;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder derivePositionAnchorFromAlignment() {
|
||||||
|
if (textAlignment == null) {
|
||||||
|
positionAnchor = Cue.TYPE_UNSET;
|
||||||
|
} else {
|
||||||
|
switch (textAlignment) {
|
||||||
|
case ALIGN_NORMAL:
|
||||||
|
positionAnchor = Cue.ANCHOR_TYPE_START;
|
||||||
|
break;
|
||||||
|
case ALIGN_CENTER:
|
||||||
|
positionAnchor = Cue.ANCHOR_TYPE_MIDDLE;
|
||||||
|
break;
|
||||||
|
case ALIGN_OPPOSITE:
|
||||||
|
positionAnchor = Cue.ANCHOR_TYPE_END;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.w(TAG, "Unrecognized alignment: " + textAlignment);
|
||||||
|
positionAnchor = Cue.ANCHOR_TYPE_START;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser for webvtt cue text. (https://w3c.github.io/webvtt/#cue-text)
|
* Parser for WebVTT cues. (https://w3c.github.io/webvtt/#cues)
|
||||||
*/
|
*/
|
||||||
public final class WebvttCueParser {
|
public final class WebvttCueParser {
|
||||||
|
|
||||||
@ -66,71 +66,50 @@ public final class WebvttCueParser {
|
|||||||
|
|
||||||
private static final String TAG = "WebvttCueParser";
|
private static final String TAG = "WebvttCueParser";
|
||||||
|
|
||||||
private StringBuilder textBuilder;
|
private final StringBuilder textBuilder;
|
||||||
private PositionHolder positionHolder;
|
|
||||||
|
|
||||||
public WebvttCueParser() {
|
public WebvttCueParser() {
|
||||||
positionHolder = new PositionHolder();
|
|
||||||
textBuilder = new StringBuilder();
|
textBuilder = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the next valid Webvtt cue in a parsable array, including timestamps, settings and text.
|
* Parses the next valid WebVTT cue in a parsable array, including timestamps, settings and text.
|
||||||
*
|
*
|
||||||
* @param webvttData parsable Webvtt file data.
|
* @param webvttData Parsable WebVTT file data.
|
||||||
* @return a {@link WebvttCue} instance if cue content is found. {@code null} otherwise.
|
* @param cueBuilder Builder for WebVTT Cues.
|
||||||
|
* @return True if a valid Cue was found, false otherwise.
|
||||||
*/
|
*/
|
||||||
public WebvttCue parseNextValidCue(ParsableByteArray webvttData) {
|
public boolean parseNextValidCue(ParsableByteArray webvttData, WebvttCue.Builder cueBuilder) {
|
||||||
Matcher cueHeaderMatcher;
|
Matcher cueHeaderMatcher;
|
||||||
while ((cueHeaderMatcher = findNextCueHeader(webvttData)) != null) {
|
while ((cueHeaderMatcher = findNextCueHeader(webvttData)) != null) {
|
||||||
WebvttCue currentCue = parseCue(cueHeaderMatcher, webvttData);
|
if (parseCue(cueHeaderMatcher, webvttData, cueBuilder, textBuilder)) {
|
||||||
if (currentCue != null) {
|
return true;
|
||||||
return currentCue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebvttCue parseCue(Matcher cueHeaderMatcher, ParsableByteArray webvttData) {
|
/**
|
||||||
long cueStartTime;
|
* Parses a string containing a list of cue settings.
|
||||||
long cueEndTime;
|
*
|
||||||
try {
|
* @param cueSettingsList String containing the settings for a given cue.
|
||||||
// Parse the cue start and end times.
|
* @param builder The {@link WebvttCue.Builder} where incremental construction takes place.
|
||||||
cueStartTime = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1));
|
*/
|
||||||
cueEndTime = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(2));
|
public static void parseCueSettingsList(String cueSettingsList, WebvttCue.Builder builder) {
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Log.w(TAG, "Skipping cue with bad header: " + cueHeaderMatcher.group());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default cue settings.
|
|
||||||
Alignment cueTextAlignment = null;
|
|
||||||
float cueLine = Cue.DIMEN_UNSET;
|
|
||||||
int cueLineType = Cue.TYPE_UNSET;
|
|
||||||
int cueLineAnchor = Cue.TYPE_UNSET;
|
|
||||||
float cuePosition = Cue.DIMEN_UNSET;
|
|
||||||
int cuePositionAnchor = Cue.TYPE_UNSET;
|
|
||||||
float cueWidth = Cue.DIMEN_UNSET;
|
|
||||||
|
|
||||||
// Parse the cue settings list.
|
// Parse the cue settings list.
|
||||||
Matcher cueSettingMatcher = CUE_SETTING_PATTERN.matcher(cueHeaderMatcher.group(3));
|
Matcher cueSettingMatcher = CUE_SETTING_PATTERN.matcher(cueSettingsList);
|
||||||
while (cueSettingMatcher.find()) {
|
while (cueSettingMatcher.find()) {
|
||||||
String name = cueSettingMatcher.group(1);
|
String name = cueSettingMatcher.group(1);
|
||||||
String value = cueSettingMatcher.group(2);
|
String value = cueSettingMatcher.group(2);
|
||||||
try {
|
try {
|
||||||
if ("line".equals(name)) {
|
if ("line".equals(name)) {
|
||||||
parseLineAttribute(value, positionHolder);
|
parseLineAttribute(value, builder);
|
||||||
cueLine = positionHolder.position;
|
|
||||||
cueLineType = positionHolder.lineType;
|
|
||||||
cueLineAnchor = positionHolder.positionAnchor;
|
|
||||||
} else if ("align".equals(name)) {
|
} else if ("align".equals(name)) {
|
||||||
cueTextAlignment = parseTextAlignment(value);
|
builder.setTextAlignment(parseTextAlignment(value));
|
||||||
} else if ("position".equals(name)) {
|
} else if ("position".equals(name)) {
|
||||||
parsePositionAttribute(value, positionHolder);
|
parsePositionAttribute(value, builder);
|
||||||
cuePosition = positionHolder.position;
|
|
||||||
cuePositionAnchor = positionHolder.positionAnchor;
|
|
||||||
} else if ("size".equals(name)) {
|
} else if ("size".equals(name)) {
|
||||||
cueWidth = WebvttParserUtil.parsePercentage(value);
|
builder.setWidth(WebvttParserUtil.parsePercentage(value));
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Unknown cue setting " + name + ":" + value);
|
Log.w(TAG, "Unknown cue setting " + name + ":" + value);
|
||||||
}
|
}
|
||||||
@ -138,13 +117,45 @@ public final class WebvttCueParser {
|
|||||||
Log.w(TAG, "Skipping bad cue setting: " + cueSettingMatcher.group());
|
Log.w(TAG, "Skipping bad cue setting: " + cueSettingMatcher.group());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cuePosition != Cue.DIMEN_UNSET && cuePositionAnchor == Cue.TYPE_UNSET) {
|
|
||||||
// Computed position alignment should be derived from the text alignment if it has not been
|
|
||||||
// set explicitly.
|
|
||||||
cuePositionAnchor = alignmentToAnchor(cueTextAlignment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads lines up to and including the next WebVTT cue header.
|
||||||
|
*
|
||||||
|
* @param input The input from which lines should be read.
|
||||||
|
* @return A {@link Matcher} for the WebVTT cue header, or null if the end of the input was
|
||||||
|
* reached without a cue header being found. In the case that a cue header is found, groups 1,
|
||||||
|
* 2 and 3 of the returned matcher contain the start time, end time and settings list.
|
||||||
|
*/
|
||||||
|
public static Matcher findNextCueHeader(ParsableByteArray input) {
|
||||||
|
String line;
|
||||||
|
while ((line = input.readLine()) != null) {
|
||||||
|
if (COMMENT.matcher(line).matches()) {
|
||||||
|
// Skip until the end of the comment block.
|
||||||
|
while ((line = input.readLine()) != null && !line.isEmpty()) {}
|
||||||
|
} else {
|
||||||
|
Matcher cueHeaderMatcher = WebvttCueParser.CUE_HEADER_PATTERN.matcher(line);
|
||||||
|
if (cueHeaderMatcher.matches()) {
|
||||||
|
return cueHeaderMatcher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean parseCue(Matcher cueHeaderMatcher, ParsableByteArray webvttData,
|
||||||
|
WebvttCue.Builder builder, StringBuilder textBuilder) {
|
||||||
|
try {
|
||||||
|
// Parse the cue start and end times.
|
||||||
|
builder.setStartTime(WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1)))
|
||||||
|
.setEndTime(WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(2)));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.w(TAG, "Skipping cue with bad header: " + cueHeaderMatcher.group());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseCueSettingsList(cueHeaderMatcher.group(3), builder);
|
||||||
|
|
||||||
// Parse the cue text.
|
// Parse the cue text.
|
||||||
textBuilder.setLength(0);
|
textBuilder.setLength(0);
|
||||||
String line;
|
String line;
|
||||||
@ -154,11 +165,8 @@ public final class WebvttCueParser {
|
|||||||
}
|
}
|
||||||
textBuilder.append(line.trim());
|
textBuilder.append(line.trim());
|
||||||
}
|
}
|
||||||
|
builder.setText(parseCueText(textBuilder.toString()));
|
||||||
CharSequence cueText = parseCueText(textBuilder.toString());
|
return true;
|
||||||
|
|
||||||
return new WebvttCue(cueStartTime, cueEndTime, cueText, cueTextAlignment, cueLine,
|
|
||||||
cueLineType, cueLineAnchor, cuePosition, cuePositionAnchor, cueWidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static Spanned parseCueText(String markup) {
|
/* package */ static Spanned parseCueText(String markup) {
|
||||||
@ -226,77 +234,34 @@ public final class WebvttCueParser {
|
|||||||
return spannedText;
|
return spannedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads lines up to and including the next WebVTT cue header.
|
|
||||||
*
|
|
||||||
* @param input The input from which lines should be read.
|
|
||||||
* @return A {@link Matcher} for the WebVTT cue header, or null if the end of the input was
|
|
||||||
* reached without a cue header being found. In the case that a cue header is found, groups 1,
|
|
||||||
* 2 and 3 of the returned matcher contain the start time, end time and settings list.
|
|
||||||
*/
|
|
||||||
public static Matcher findNextCueHeader(ParsableByteArray input) {
|
|
||||||
String line;
|
|
||||||
while ((line = input.readLine()) != null) {
|
|
||||||
if (COMMENT.matcher(line).matches()) {
|
|
||||||
// Skip until the end of the comment block.
|
|
||||||
while ((line = input.readLine()) != null && !line.isEmpty()) {}
|
|
||||||
} else {
|
|
||||||
Matcher cueHeaderMatcher = WebvttCueParser.CUE_HEADER_PATTERN.matcher(line);
|
|
||||||
if (cueHeaderMatcher.matches()) {
|
|
||||||
return cueHeaderMatcher;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class PositionHolder {
|
|
||||||
|
|
||||||
public float position;
|
|
||||||
public int positionAnchor;
|
|
||||||
public int lineType;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal methods
|
// Internal methods
|
||||||
|
|
||||||
private static void parseLineAttribute(String s, PositionHolder out)
|
private static void parseLineAttribute(String s, WebvttCue.Builder builder)
|
||||||
throws NumberFormatException {
|
throws NumberFormatException {
|
||||||
int lineAnchor;
|
|
||||||
int commaPosition = s.indexOf(',');
|
int commaPosition = s.indexOf(',');
|
||||||
if (commaPosition != -1) {
|
if (commaPosition != -1) {
|
||||||
lineAnchor = parsePositionAnchor(s.substring(commaPosition + 1));
|
builder.setLineAnchor(parsePositionAnchor(s.substring(commaPosition + 1)));
|
||||||
s = s.substring(0, commaPosition);
|
s = s.substring(0, commaPosition);
|
||||||
} else {
|
} else {
|
||||||
lineAnchor = Cue.TYPE_UNSET;
|
builder.setLineAnchor(Cue.TYPE_UNSET);
|
||||||
}
|
}
|
||||||
float line;
|
|
||||||
int lineType;
|
|
||||||
if (s.endsWith("%")) {
|
if (s.endsWith("%")) {
|
||||||
line = WebvttParserUtil.parsePercentage(s);
|
builder.setLine(WebvttParserUtil.parsePercentage(s)).setLineType(Cue.LINE_TYPE_FRACTION);
|
||||||
lineType = Cue.LINE_TYPE_FRACTION;
|
|
||||||
} else {
|
} else {
|
||||||
line = Integer.parseInt(s);
|
builder.setLine(Integer.parseInt(s)).setLineType(Cue.LINE_TYPE_NUMBER);
|
||||||
lineType = Cue.LINE_TYPE_NUMBER;
|
|
||||||
}
|
}
|
||||||
out.position = line;
|
|
||||||
out.positionAnchor = lineAnchor;
|
|
||||||
out.lineType = lineType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parsePositionAttribute(String s, PositionHolder out)
|
private static void parsePositionAttribute(String s, WebvttCue.Builder builder)
|
||||||
throws NumberFormatException {
|
throws NumberFormatException {
|
||||||
int positionAnchor;
|
|
||||||
int commaPosition = s.indexOf(',');
|
int commaPosition = s.indexOf(',');
|
||||||
if (commaPosition != -1) {
|
if (commaPosition != -1) {
|
||||||
positionAnchor = parsePositionAnchor(s.substring(commaPosition + 1));
|
builder.setPositionAnchor(parsePositionAnchor(s.substring(commaPosition + 1)));
|
||||||
s = s.substring(0, commaPosition);
|
s = s.substring(0, commaPosition);
|
||||||
} else {
|
} else {
|
||||||
positionAnchor = Cue.TYPE_UNSET;
|
builder.setPositionAnchor(Cue.TYPE_UNSET);
|
||||||
}
|
}
|
||||||
out.position = WebvttParserUtil.parsePercentage(s);
|
builder.setPosition(WebvttParserUtil.parsePercentage(s));
|
||||||
out.positionAnchor = positionAnchor;
|
|
||||||
out.lineType = Cue.TYPE_UNSET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int parsePositionAnchor(String s) {
|
private static int parsePositionAnchor(String s) {
|
||||||
@ -329,27 +294,10 @@ public final class WebvttCueParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int alignmentToAnchor(Alignment alignment) {
|
|
||||||
if (alignment == null) {
|
|
||||||
return Cue.TYPE_UNSET;
|
|
||||||
}
|
|
||||||
switch (alignment) {
|
|
||||||
case ALIGN_NORMAL:
|
|
||||||
return Cue.ANCHOR_TYPE_START;
|
|
||||||
case ALIGN_CENTER:
|
|
||||||
return Cue.ANCHOR_TYPE_MIDDLE;
|
|
||||||
case ALIGN_OPPOSITE:
|
|
||||||
return Cue.ANCHOR_TYPE_END;
|
|
||||||
default:
|
|
||||||
Log.w(TAG, "Unrecognized alignment: " + alignment);
|
|
||||||
return Cue.ANCHOR_TYPE_START;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find end of tag (>). The position returned is the position of the > plus one (exclusive).
|
* Find end of tag (>). The position returned is the position of the > plus one (exclusive).
|
||||||
*
|
*
|
||||||
* @param markup The webvtt cue markup to be parsed.
|
* @param markup The WebVTT cue markup to be parsed.
|
||||||
* @param startPos the position from where to start searching for the end of tag.
|
* @param startPos the position from where to start searching for the end of tag.
|
||||||
* @return the position of the end of tag plus 1 (one).
|
* @return the position of the end of tag plus 1 (one).
|
||||||
*/
|
*/
|
||||||
|
@ -33,10 +33,12 @@ public final class WebvttParser implements SubtitleParser {
|
|||||||
|
|
||||||
private final WebvttCueParser cueParser;
|
private final WebvttCueParser cueParser;
|
||||||
private final ParsableByteArray parsableWebvttData;
|
private final ParsableByteArray parsableWebvttData;
|
||||||
|
private final WebvttCue.Builder webvttCueBuilder;
|
||||||
|
|
||||||
public WebvttParser() {
|
public WebvttParser() {
|
||||||
cueParser = new WebvttCueParser();
|
cueParser = new WebvttCueParser();
|
||||||
parsableWebvttData = new ParsableByteArray();
|
parsableWebvttData = new ParsableByteArray();
|
||||||
|
webvttCueBuilder = new WebvttCue.Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,6 +50,7 @@ public final class WebvttParser implements SubtitleParser {
|
|||||||
public final WebvttSubtitle parse(byte[] bytes, int offset, int length) throws ParserException {
|
public final WebvttSubtitle parse(byte[] bytes, int offset, int length) throws ParserException {
|
||||||
parsableWebvttData.reset(bytes, offset + length);
|
parsableWebvttData.reset(bytes, offset + length);
|
||||||
parsableWebvttData.setPosition(offset);
|
parsableWebvttData.setPosition(offset);
|
||||||
|
webvttCueBuilder.reset(); // In case a previous parse run failed with a ParserException.
|
||||||
|
|
||||||
// Validate the first line of the header, and skip the remainder.
|
// Validate the first line of the header, and skip the remainder.
|
||||||
WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
|
WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
|
||||||
@ -55,9 +58,9 @@ public final class WebvttParser implements SubtitleParser {
|
|||||||
|
|
||||||
// Extract Cues
|
// Extract Cues
|
||||||
ArrayList<WebvttCue> subtitles = new ArrayList<>();
|
ArrayList<WebvttCue> subtitles = new ArrayList<>();
|
||||||
WebvttCue currentWebvttCue;
|
while (cueParser.parseNextValidCue(parsableWebvttData, webvttCueBuilder)) {
|
||||||
while ((currentWebvttCue = cueParser.parseNextValidCue(parsableWebvttData)) != null) {
|
subtitles.add(webvttCueBuilder.build());
|
||||||
subtitles.add(currentWebvttCue);
|
webvttCueBuilder.reset();
|
||||||
}
|
}
|
||||||
return new WebvttSubtitle(subtitles);
|
return new WebvttSubtitle(subtitles);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user