Java源码示例:com.google.android.exoplayer2.text.Subtitle
示例1
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
// Webvtt in Mp4 samples have boxes inside of them, so we have to do a traditional box parsing:
// first 4 bytes size and then 4 bytes type.
sampleData.reset(bytes, length);
List<Cue> resultingCueList = new ArrayList<>();
while (sampleData.bytesLeft() > 0) {
if (sampleData.bytesLeft() < BOX_HEADER_SIZE) {
throw new SubtitleDecoderException("Incomplete Mp4Webvtt Top Level box header found.");
}
int boxSize = sampleData.readInt();
int boxType = sampleData.readInt();
if (boxType == TYPE_vttc) {
resultingCueList.add(parseVttCueBox(sampleData, builder, boxSize - BOX_HEADER_SIZE));
} else {
// Peers of the VTTCueBox are still not supported and are skipped.
sampleData.skipBytes(boxSize - BOX_HEADER_SIZE);
}
}
return new Mp4WebvttSubtitle(resultingCueList);
}
示例2
@Override
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
if (maybeInflateData(data, size)) {
buffer.reset(inflatedData, inflatedDataSize);
} else {
buffer.reset(data, size);
}
cueBuilder.reset();
ArrayList<Cue> cues = new ArrayList<>();
while (buffer.bytesLeft() >= 3) {
Cue cue = readNextSection(buffer, cueBuilder);
if (cue != null) {
cues.add(cue);
}
}
return new PgsSubtitle(Collections.unmodifiableList(cues));
}
示例3
@Override
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
if (maybeInflateData(data, size)) {
buffer.reset(inflatedData, inflatedDataSize);
} else {
buffer.reset(data, size);
}
cueBuilder.reset();
ArrayList<Cue> cues = new ArrayList<>();
while (buffer.bytesLeft() >= 3) {
Cue cue = readNextSection(buffer, cueBuilder);
if (cue != null) {
cues.add(cue);
}
}
return new PgsSubtitle(Collections.unmodifiableList(cues));
}
示例4
@Override
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
buffer.reset(data, size);
maybeInflateData(buffer);
cueBuilder.reset();
ArrayList<Cue> cues = new ArrayList<>();
while (buffer.bytesLeft() >= 3) {
Cue cue = readNextSection(buffer, cueBuilder);
if (cue != null) {
cues.add(cue);
}
}
return new PgsSubtitle(Collections.unmodifiableList(cues));
}
示例5
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
parsableWebvttData.reset(bytes, length);
// Initialization for consistent starting state.
webvttCueBuilder.reset();
definedStyles.clear();
// Validate the first line of the header, and skip the remainder.
try {
WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
} catch (ParserException e) {
throw new SubtitleDecoderException(e);
}
while (!TextUtils.isEmpty(parsableWebvttData.readLine())) {}
int event;
ArrayList<WebvttCue> subtitles = new ArrayList<>();
while ((event = getNextEvent(parsableWebvttData)) != EVENT_END_OF_FILE) {
if (event == EVENT_COMMENT) {
skipComment(parsableWebvttData);
} else if (event == EVENT_STYLE_BLOCK) {
if (!subtitles.isEmpty()) {
throw new SubtitleDecoderException("A style block was found after the first cue.");
}
parsableWebvttData.readLine(); // Consume the "STYLE" header.
definedStyles.addAll(cssParser.parseBlock(parsableWebvttData));
} else if (event == EVENT_CUE) {
if (cueParser.parseCue(parsableWebvttData, webvttCueBuilder, definedStyles)) {
subtitles.add(webvttCueBuilder.build());
webvttCueBuilder.reset();
}
}
}
return new WebvttSubtitle(subtitles);
}
示例6
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset) {
List<List<Cue>> cues = new ArrayList<>();
List<Long> cueTimesUs = new ArrayList<>();
ParsableByteArray data = new ParsableByteArray(bytes, length);
if (!haveInitializationData) {
parseHeader(data);
}
parseEventBody(data, cues, cueTimesUs);
return new SsaSubtitle(cues, cueTimesUs);
}
示例7
@Override
protected Subtitle decode(byte[] data, int length, boolean reset) {
if (reset) {
parser.reset();
}
return new DvbSubtitle(parser.decode(data, length));
}
示例8
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
parsableByteArray.reset(bytes, length);
String cueTextString = readSubtitleText(parsableByteArray);
if (cueTextString.isEmpty()) {
return Tx3gSubtitle.EMPTY;
}
// Attach default styles.
SpannableStringBuilder cueText = new SpannableStringBuilder(cueTextString);
attachFontFace(cueText, defaultFontFace, DEFAULT_FONT_FACE, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachColor(cueText, defaultColorRgba, DEFAULT_COLOR, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachFontFamily(cueText, defaultFontFamily, DEFAULT_FONT_FAMILY, 0, cueText.length(),
SPAN_PRIORITY_LOW);
float verticalPlacement = defaultVerticalPlacement;
// Find and attach additional styles.
while (parsableByteArray.bytesLeft() >= SIZE_ATOM_HEADER) {
int position = parsableByteArray.getPosition();
int atomSize = parsableByteArray.readInt();
int atomType = parsableByteArray.readInt();
if (atomType == TYPE_STYL) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int styleRecordCount = parsableByteArray.readUnsignedShort();
for (int i = 0; i < styleRecordCount; i++) {
applyStyleRecord(parsableByteArray, cueText);
}
} else if (atomType == TYPE_TBOX && customVerticalPlacement) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int requestedVerticalPlacement = parsableByteArray.readUnsignedShort();
verticalPlacement = (float) requestedVerticalPlacement / calculatedVideoTrackHeight;
verticalPlacement = Util.constrainValue(verticalPlacement, 0.0f, 0.95f);
}
parsableByteArray.setPosition(position + atomSize);
}
return new Tx3gSubtitle(new Cue(cueText, null, verticalPlacement, Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_START, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET));
}
示例9
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
parsableByteArray.reset(bytes, length);
String cueTextString = readSubtitleText(parsableByteArray);
if (cueTextString.isEmpty()) {
return Tx3gSubtitle.EMPTY;
}
// Attach default styles.
SpannableStringBuilder cueText = new SpannableStringBuilder(cueTextString);
attachFontFace(cueText, defaultFontFace, DEFAULT_FONT_FACE, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachColor(cueText, defaultColorRgba, DEFAULT_COLOR, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachFontFamily(cueText, defaultFontFamily, DEFAULT_FONT_FAMILY, 0, cueText.length(),
SPAN_PRIORITY_LOW);
float verticalPlacement = defaultVerticalPlacement;
// Find and attach additional styles.
while (parsableByteArray.bytesLeft() >= SIZE_ATOM_HEADER) {
int position = parsableByteArray.getPosition();
int atomSize = parsableByteArray.readInt();
int atomType = parsableByteArray.readInt();
if (atomType == TYPE_STYL) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int styleRecordCount = parsableByteArray.readUnsignedShort();
for (int i = 0; i < styleRecordCount; i++) {
applyStyleRecord(parsableByteArray, cueText);
}
} else if (atomType == TYPE_TBOX && customVerticalPlacement) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int requestedVerticalPlacement = parsableByteArray.readUnsignedShort();
verticalPlacement = (float) requestedVerticalPlacement / calculatedVideoTrackHeight;
verticalPlacement = Util.constrainValue(verticalPlacement, 0.0f, 0.95f);
}
parsableByteArray.setPosition(position + atomSize);
}
return new Tx3gSubtitle(new Cue(cueText, null, verticalPlacement, Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_START, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET));
}
示例10
@Override
protected Subtitle decode(byte[] bytes, int length) {
parsableByteArray.reset(bytes, length);
int textLength = parsableByteArray.readUnsignedShort();
if (textLength == 0) {
return Tx3gSubtitle.EMPTY;
}
String cueText = parsableByteArray.readString(textLength);
return new Tx3gSubtitle(new Cue(cueText));
}
示例11
@Override
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
buffer.reset(data, size);
maybeInflateData(buffer);
cueBuilder.reset();
ArrayList<Cue> cues = new ArrayList<>();
while (buffer.bytesLeft() >= 3) {
Cue cue = readNextSection(buffer, cueBuilder);
if (cue != null) {
cues.add(cue);
}
}
return new PgsSubtitle(Collections.unmodifiableList(cues));
}
示例12
@Override
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
buffer.reset(data, size);
maybeInflateData(buffer);
cueBuilder.reset();
ArrayList<Cue> cues = new ArrayList<>();
while (buffer.bytesLeft() >= 3) {
Cue cue = readNextSection(buffer, cueBuilder);
if (cue != null) {
cues.add(cue);
}
}
return new PgsSubtitle(Collections.unmodifiableList(cues));
}
示例13
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
parsableByteArray.reset(bytes, length);
String cueTextString = readSubtitleText(parsableByteArray);
if (cueTextString.isEmpty()) {
return Tx3gSubtitle.EMPTY;
}
// Attach default styles.
SpannableStringBuilder cueText = new SpannableStringBuilder(cueTextString);
attachFontFace(cueText, defaultFontFace, DEFAULT_FONT_FACE, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachColor(cueText, defaultColorRgba, DEFAULT_COLOR, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachFontFamily(cueText, defaultFontFamily, DEFAULT_FONT_FAMILY, 0, cueText.length(),
SPAN_PRIORITY_LOW);
float verticalPlacement = defaultVerticalPlacement;
// Find and attach additional styles.
while (parsableByteArray.bytesLeft() >= SIZE_ATOM_HEADER) {
int position = parsableByteArray.getPosition();
int atomSize = parsableByteArray.readInt();
int atomType = parsableByteArray.readInt();
if (atomType == TYPE_STYL) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int styleRecordCount = parsableByteArray.readUnsignedShort();
for (int i = 0; i < styleRecordCount; i++) {
applyStyleRecord(parsableByteArray, cueText);
}
} else if (atomType == TYPE_TBOX && customVerticalPlacement) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int requestedVerticalPlacement = parsableByteArray.readUnsignedShort();
verticalPlacement = (float) requestedVerticalPlacement / calculatedVideoTrackHeight;
verticalPlacement = Util.constrainValue(verticalPlacement, 0.0f, 0.95f);
}
parsableByteArray.setPosition(position + atomSize);
}
return new Tx3gSubtitle(
new Cue(
cueText,
/* textAlignment= */ null,
verticalPlacement,
Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_START,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET));
}
示例14
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例15
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例16
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset) {
ArrayList<Cue> cues = new ArrayList<>();
LongArray cueTimesUs = new LongArray();
ParsableByteArray subripData = new ParsableByteArray(bytes, length);
@Nullable String currentLine;
while ((currentLine = subripData.readLine()) != null) {
if (currentLine.length() == 0) {
// Skip blank lines.
continue;
}
// Parse the index line as a sanity check.
try {
Integer.parseInt(currentLine);
} catch (NumberFormatException e) {
Log.w(TAG, "Skipping invalid index: " + currentLine);
continue;
}
// Read and parse the timing line.
currentLine = subripData.readLine();
if (currentLine == null) {
Log.w(TAG, "Unexpected end");
break;
}
Matcher matcher = SUBRIP_TIMING_LINE.matcher(currentLine);
if (matcher.matches()) {
cueTimesUs.add(parseTimecode(matcher, /* groupOffset= */ 1));
cueTimesUs.add(parseTimecode(matcher, /* groupOffset= */ 6));
} else {
Log.w(TAG, "Skipping invalid timing: " + currentLine);
continue;
}
// Read and parse the text and tags.
textBuilder.setLength(0);
tags.clear();
currentLine = subripData.readLine();
while (!TextUtils.isEmpty(currentLine)) {
if (textBuilder.length() > 0) {
textBuilder.append("<br>");
}
textBuilder.append(processLine(currentLine, tags));
currentLine = subripData.readLine();
}
Spanned text = Html.fromHtml(textBuilder.toString());
@Nullable String alignmentTag = null;
for (int i = 0; i < tags.size(); i++) {
String tag = tags.get(i);
if (tag.matches(SUBRIP_ALIGNMENT_TAG)) {
alignmentTag = tag;
// Subsequent alignment tags should be ignored.
break;
}
}
cues.add(buildCue(text, alignmentTag));
cues.add(Cue.EMPTY);
}
Cue[] cuesArray = new Cue[cues.size()];
cues.toArray(cuesArray);
long[] cueTimesUsArray = cueTimesUs.toArray();
return new SubripSubtitle(cuesArray, cueTimesUsArray);
}
示例17
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例18
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例19
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例20
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例21
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例22
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例23
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
parsableByteArray.reset(bytes, length);
String cueTextString = readSubtitleText(parsableByteArray);
if (cueTextString.isEmpty()) {
return Tx3gSubtitle.EMPTY;
}
// Attach default styles.
SpannableStringBuilder cueText = new SpannableStringBuilder(cueTextString);
attachFontFace(cueText, defaultFontFace, DEFAULT_FONT_FACE, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachColor(cueText, defaultColorRgba, DEFAULT_COLOR, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachFontFamily(cueText, defaultFontFamily, DEFAULT_FONT_FAMILY, 0, cueText.length(),
SPAN_PRIORITY_LOW);
float verticalPlacement = defaultVerticalPlacement;
// Find and attach additional styles.
while (parsableByteArray.bytesLeft() >= SIZE_ATOM_HEADER) {
int position = parsableByteArray.getPosition();
int atomSize = parsableByteArray.readInt();
int atomType = parsableByteArray.readInt();
if (atomType == TYPE_STYL) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int styleRecordCount = parsableByteArray.readUnsignedShort();
for (int i = 0; i < styleRecordCount; i++) {
applyStyleRecord(parsableByteArray, cueText);
}
} else if (atomType == TYPE_TBOX && customVerticalPlacement) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int requestedVerticalPlacement = parsableByteArray.readUnsignedShort();
verticalPlacement = (float) requestedVerticalPlacement / calculatedVideoTrackHeight;
verticalPlacement = Util.constrainValue(verticalPlacement, 0.0f, 0.95f);
}
parsableByteArray.setPosition(position + atomSize);
}
return new Tx3gSubtitle(
new Cue(
cueText,
/* textAlignment= */ null,
verticalPlacement,
Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_START,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET));
}
示例24
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例25
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例26
@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset)
throws SubtitleDecoderException {
parsableByteArray.reset(bytes, length);
String cueTextString = readSubtitleText(parsableByteArray);
if (cueTextString.isEmpty()) {
return Tx3gSubtitle.EMPTY;
}
// Attach default styles.
SpannableStringBuilder cueText = new SpannableStringBuilder(cueTextString);
attachFontFace(cueText, defaultFontFace, DEFAULT_FONT_FACE, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachColor(cueText, defaultColorRgba, DEFAULT_COLOR, 0, cueText.length(),
SPAN_PRIORITY_LOW);
attachFontFamily(cueText, defaultFontFamily, DEFAULT_FONT_FAMILY, 0, cueText.length(),
SPAN_PRIORITY_LOW);
float verticalPlacement = defaultVerticalPlacement;
// Find and attach additional styles.
while (parsableByteArray.bytesLeft() >= SIZE_ATOM_HEADER) {
int position = parsableByteArray.getPosition();
int atomSize = parsableByteArray.readInt();
int atomType = parsableByteArray.readInt();
if (atomType == TYPE_STYL) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int styleRecordCount = parsableByteArray.readUnsignedShort();
for (int i = 0; i < styleRecordCount; i++) {
applyStyleRecord(parsableByteArray, cueText);
}
} else if (atomType == TYPE_TBOX && customVerticalPlacement) {
assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
int requestedVerticalPlacement = parsableByteArray.readUnsignedShort();
verticalPlacement = (float) requestedVerticalPlacement / calculatedVideoTrackHeight;
verticalPlacement = Util.constrainValue(verticalPlacement, 0.0f, 0.95f);
}
parsableByteArray.setPosition(position + atomSize);
}
return new Tx3gSubtitle(
new Cue(
cueText,
/* textAlignment= */ null,
verticalPlacement,
Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_START,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET));
}
示例27
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例28
@Override
protected Subtitle createSubtitle() {
lastCues = cues;
return new CeaSubtitle(cues);
}
示例29
/**
* Creates a {@link Subtitle} from the available data.
*/
protected abstract Subtitle createSubtitle();
示例30
/**
* Creates a {@link Subtitle} from the available data.
*/
protected abstract Subtitle createSubtitle();