boolean onMasterElementStart( int id, long elementOffsetBytes, int headerSizeBytes, long contentsSizeBytes) throws ParserException { switch (id) { case ID_SEGMENT: if (segmentStartOffsetBytes != UNKNOWN || segmentEndOffsetBytes != UNKNOWN) { throw new ParserException("Multiple Segment elements not supported"); } segmentStartOffsetBytes = elementOffsetBytes + headerSizeBytes; segmentEndOffsetBytes = elementOffsetBytes + headerSizeBytes + contentsSizeBytes; break; case ID_CUES: cuesSizeBytes = headerSizeBytes + contentsSizeBytes; cueTimesUs = new LongArray(); cueClusterPositions = new LongArray(); break; default: // pass } return true; }
boolean onMasterElementStart( int id, long elementOffsetBytes, int headerSizeBytes, long contentsSizeBytes) { switch (id) { case ID_SEGMENT: if (segmentStartOffsetBytes != UNKNOWN || segmentEndOffsetBytes != UNKNOWN) { throw new IllegalStateException("Multiple Segment elements not supported"); } segmentStartOffsetBytes = elementOffsetBytes + headerSizeBytes; segmentEndOffsetBytes = elementOffsetBytes + headerSizeBytes + contentsSizeBytes; break; case ID_CUES: cuesSizeBytes = headerSizeBytes + contentsSizeBytes; cueTimesUs = new LongArray(); cueClusterPositions = new LongArray(); break; default: // pass } return true; }
void startMasterElement(int id, long contentPosition, long contentSize) throws ParserException { switch (id) { case ID_SEGMENT: if (segmentContentPosition != UNKNOWN && segmentContentPosition != contentPosition) { throw new ParserException("Multiple Segment elements not supported"); } segmentContentPosition = contentPosition; segmentContentSize = contentSize; return; case ID_SEEK: seekEntryId = UNKNOWN; seekEntryPosition = UNKNOWN; return; case ID_CUES: cueTimesUs = new LongArray(); cueClusterPositions = new LongArray(); return; case ID_CUE_POINT: seenClusterPositionForCurrentCuePoint = false; return; case ID_CLUSTER: if (cuesState == CUES_STATE_NOT_BUILT) { // We need to build cues before parsing the cluster. if (cuesContentPosition != UNKNOWN) { // We know where the Cues element is located. Seek to request it. seekForCues = true; } else { // We don't know where the Cues element is located. It's most likely omitted. Allow // playback, but disable seeking. extractorOutput.seekMap(SeekMap.UNSEEKABLE); cuesState = CUES_STATE_BUILT; } } return; case ID_BLOCK_GROUP: sampleSeenReferenceBlock = false; return; case ID_CONTENT_ENCODING: // TODO: check and fail if more than one content encoding is present. return; case ID_CONTENT_ENCRYPTION: trackFormat.hasContentEncryption = true; return; case ID_TRACK_ENTRY: trackFormat = new TrackFormat(); return; default: return; } }
@Override public SubripSubtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) throws IOException { ArrayList<Cue> cues = new ArrayList<>(); LongArray cueTimesUs = new LongArray(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, C.UTF8_NAME)); String currentLine; while ((currentLine = reader.readLine()) != null) { // Parse the numeric counter as a sanity check. try { Integer.parseInt(currentLine); } catch (NumberFormatException e) { throw new ParserException("Expected numeric counter: " + currentLine); } // Read and parse the timing line. currentLine = reader.readLine(); Matcher matcher = SUBRIP_TIMING_LINE.matcher(currentLine); if (matcher.find()) { cueTimesUs.add(startTimeUs + parseTimestampUs(matcher.group(1))); cueTimesUs.add(startTimeUs + parseTimestampUs(matcher.group(2))); } else { throw new ParserException("Expected timing line: " + currentLine); } // Read and parse the text. textBuilder.setLength(0); while (!TextUtils.isEmpty(currentLine = reader.readLine())) { if (textBuilder.length() > 0) { textBuilder.append("<br>"); } textBuilder.append(currentLine.trim()); } Spanned text = Html.fromHtml(textBuilder.toString()); cues.add(new Cue(text)); } Cue[] cuesArray = new Cue[cues.size()]; cues.toArray(cuesArray); long[] cueTimesUsArray = cueTimesUs.toArray(); return new SubripSubtitle(startTimeUs, cuesArray, cueTimesUsArray); }
void startMasterElement(int id, long contentPosition, long contentSize) throws ParserException { switch (id) { case ID_SEGMENT: if (segmentContentPosition != UNKNOWN && segmentContentPosition != contentPosition) { throw new ParserException("Multiple Segment elements not supported"); } segmentContentPosition = contentPosition; segmentContentSize = contentSize; return; case ID_SEEK: seekEntryId = UNKNOWN; seekEntryPosition = UNKNOWN; return; case ID_CUES: cueTimesUs = new LongArray(); cueClusterPositions = new LongArray(); return; case ID_CUE_POINT: seenClusterPositionForCurrentCuePoint = false; return; case ID_CLUSTER: if (!sentSeekMap) { // We need to build cues before parsing the cluster. if (cuesContentPosition != UNKNOWN) { // We know where the Cues element is located. Seek to request it. seekForCues = true; } else { // We don't know where the Cues element is located. It's most likely omitted. Allow // playback, but disable seeking. extractorOutput.seekMap(SeekMap.UNSEEKABLE); sentSeekMap = true; } } return; case ID_BLOCK_GROUP: sampleSeenReferenceBlock = false; return; case ID_CONTENT_ENCODING: // TODO: check and fail if more than one content encoding is present. return; case ID_CONTENT_ENCRYPTION: currentTrack.hasContentEncryption = true; return; case ID_TRACK_ENTRY: currentTrack = new Track(); return; default: return; } }
@Override public SubripSubtitle parse(byte[] bytes, int offset, int length) { ArrayList<Cue> cues = new ArrayList<>(); LongArray cueTimesUs = new LongArray(); ParsableByteArray subripData = new ParsableByteArray(bytes, offset + length); subripData.setPosition(offset); boolean haveEndTimecode; 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. haveEndTimecode = false; currentLine = subripData.readLine(); Matcher matcher = SUBRIP_TIMING_LINE.matcher(currentLine); if (matcher.find()) { cueTimesUs.add(parseTimecode(matcher.group(1))); String endTimecode = matcher.group(2); if (!TextUtils.isEmpty(endTimecode)) { haveEndTimecode = true; cueTimesUs.add(parseTimecode(matcher.group(2))); } } else { Log.w(TAG, "Skipping invalid timing: " + currentLine); continue; } // Read and parse the text. textBuilder.setLength(0); while (!TextUtils.isEmpty(currentLine = subripData.readLine())) { if (textBuilder.length() > 0) { textBuilder.append("<br>"); } textBuilder.append(currentLine.trim()); } Spanned text = Html.fromHtml(textBuilder.toString()); cues.add(new Cue(text)); if (haveEndTimecode) { cues.add(null); } } Cue[] cuesArray = new Cue[cues.size()]; cues.toArray(cuesArray); long[] cueTimesUsArray = cueTimesUs.toArray(); return new SubripSubtitle(cuesArray, cueTimesUsArray); }
@Override public FlyingSubTitle parse(InputStream inputStream) throws IOException { ArrayList<Cue> cues = new ArrayList<>(); LongArray cueTimesUs = new LongArray(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, C.UTF8_NAME)); boolean haveEndTimecode; String currentLine; while ((currentLine = reader.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. haveEndTimecode = false; currentLine = reader.readLine(); Matcher matcher = SUBRIP_TIMING_LINE.matcher(currentLine); if (matcher.find()) { cueTimesUs.add(parseTimecode(matcher.group(1))); String endTimecode = matcher.group(2); if (!TextUtils.isEmpty(endTimecode)) { haveEndTimecode = true; cueTimesUs.add(parseTimecode(matcher.group(2))); } } else { Log.w(TAG, "Skipping invalid timing: " + currentLine); continue; } // Read and parse the text. textBuilder.setLength(0); while (!TextUtils.isEmpty(currentLine = reader.readLine())) { if (textBuilder.length() > 0) { textBuilder.append("<br>"); } textBuilder.append(currentLine.trim()); } Spanned text = Html.fromHtml(textBuilder.toString()); cues.add(new Cue(text)); if (haveEndTimecode) { cues.add(null); } } Cue[] cuesArray = new Cue[cues.size()]; cues.toArray(cuesArray); long[] cueTimesUsArray = cueTimesUs.toArray(); return new FlyingSubTitle(cuesArray, cueTimesUsArray); }