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();