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); }
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.adjustTsTimestamp( TimestampAdjuster.usToPts(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); }