use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.
the class Mp4WebvttDecoderTest method testTwoCuesSample.
public void testTwoCuesSample() throws SubtitleDecoderException {
Mp4WebvttDecoder decoder = new Mp4WebvttDecoder();
Subtitle result = decoder.decode(DOUBLE_CUE_SAMPLE, DOUBLE_CUE_SAMPLE.length);
Cue firstExpectedCue = new Cue("Hello World");
Cue secondExpectedCue = new Cue("Bye Bye");
assertMp4WebvttSubtitleEquals(result, firstExpectedCue, secondExpectedCue);
}
use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.
the class WebvttExtractor method processSample.
private void processSample() throws ParserException {
ParsableByteArray webvttData = new ParsableByteArray(sampleData);
// Validate the first line of the header.
try {
WebvttParserUtil.validateWebvttHeaderLine(webvttData);
} catch (SubtitleDecoderException e) {
throw new ParserException(e);
}
// Defaults to use if the header doesn't contain an X-TIMESTAMP-MAP header.
long vttTimestampUs = 0;
long tsTimestampUs = 0;
// Parse the remainder of the header looking for X-TIMESTAMP-MAP.
String line;
while (!TextUtils.isEmpty(line = webvttData.readLine())) {
if (line.startsWith("X-TIMESTAMP-MAP")) {
Matcher localTimestampMatcher = LOCAL_TIMESTAMP.matcher(line);
if (!localTimestampMatcher.find()) {
throw new ParserException("X-TIMESTAMP-MAP doesn't contain local timestamp: " + line);
}
Matcher mediaTimestampMatcher = MEDIA_TIMESTAMP.matcher(line);
if (!mediaTimestampMatcher.find()) {
throw new ParserException("X-TIMESTAMP-MAP doesn't contain media timestamp: " + line);
}
vttTimestampUs = WebvttParserUtil.parseTimestampUs(localTimestampMatcher.group(1));
tsTimestampUs = TimestampAdjuster.ptsToUs(Long.parseLong(mediaTimestampMatcher.group(1)));
}
}
// Find the first cue header and parse the start time.
Matcher cueHeaderMatcher = WebvttParserUtil.findNextCueHeader(webvttData);
if (cueHeaderMatcher == null) {
// No cues found. Don't output a sample, but still output a corresponding track.
buildTrackOutput(0);
return;
}
long firstCueTimeUs = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1));
long sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(firstCueTimeUs + tsTimestampUs - vttTimestampUs);
long subsampleOffsetUs = sampleTimeUs - firstCueTimeUs;
// Output the track.
TrackOutput trackOutput = buildTrackOutput(subsampleOffsetUs);
// Output the sample.
sampleDataWrapper.reset(sampleData, sampleSize);
trackOutput.sampleData(sampleDataWrapper, sampleSize);
trackOutput.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
}
use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.
the class CeaDecoder method dequeueOutputBuffer.
@Override
public SubtitleOutputBuffer dequeueOutputBuffer() throws SubtitleDecoderException {
if (availableOutputBuffers.isEmpty()) {
return null;
}
// be deferred until they would be applicable
while (!queuedInputBuffers.isEmpty() && queuedInputBuffers.first().timeUs <= playbackPositionUs) {
SubtitleInputBuffer inputBuffer = queuedInputBuffers.pollFirst();
// return immediately with an output buffer propagating that
if (inputBuffer.isEndOfStream()) {
SubtitleOutputBuffer outputBuffer = availableOutputBuffers.pollFirst();
outputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
releaseInputBuffer(inputBuffer);
return outputBuffer;
}
decode(inputBuffer);
// check if we have any caption updates to report
if (isNewSubtitleDataAvailable()) {
// Even if the subtitle is decode-only; we need to generate it to consume the data so it
// isn't accidentally prepended to the next subtitle
Subtitle subtitle = createSubtitle();
if (!inputBuffer.isDecodeOnly()) {
SubtitleOutputBuffer outputBuffer = availableOutputBuffers.pollFirst();
outputBuffer.setContent(inputBuffer.timeUs, subtitle, Format.OFFSET_SAMPLE_RELATIVE);
releaseInputBuffer(inputBuffer);
return outputBuffer;
}
}
releaseInputBuffer(inputBuffer);
}
return null;
}
use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.
the class WebvttDecoder method decode.
@Override
protected WebvttSubtitle decode(byte[] bytes, int length) 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.
WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
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.");
}
// Consume the "STYLE" header.
parsableWebvttData.readLine();
WebvttCssStyle styleBlock = cssParser.parseBlock(parsableWebvttData);
if (styleBlock != null) {
definedStyles.add(styleBlock);
}
} else if (event == EVENT_CUE) {
if (cueParser.parseCue(parsableWebvttData, webvttCueBuilder, definedStyles)) {
subtitles.add(webvttCueBuilder.build());
webvttCueBuilder.reset();
}
}
}
return new WebvttSubtitle(subtitles);
}
Aggregations