com.google.android.exoplayer2.text.Cue Java Examples

The following examples show how to use com.google.android.exoplayer2.text.Cue. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Mp4WebvttDecoder.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
protected Mp4WebvttSubtitle 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);
}
 
Example #2
Source File: SsaDecoder.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
@Override
protected SsaSubtitle decode(byte[] bytes, int length, boolean reset) {
  ArrayList<Cue> cues = new ArrayList<>();
  LongArray cueTimesUs = new LongArray();

  ParsableByteArray data = new ParsableByteArray(bytes, length);
  if (!haveInitializationData) {
    parseHeader(data);
  }
  parseEventBody(data, cues, cueTimesUs);

  Cue[] cuesArray = new Cue[cues.size()];
  cues.toArray(cuesArray);
  long[] cueTimesUsArray = cueTimesUs.toArray();
  return new SsaSubtitle(cuesArray, cueTimesUsArray);
}
 
Example #3
Source File: SsaDecoder.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
@Cue.AnchorType
private static int toPositionAnchor(@SsaStyle.SsaAlignment int alignment) {
  switch (alignment) {
    case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT:
    case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT:
    case SsaStyle.SSA_ALIGNMENT_TOP_LEFT:
      return Cue.ANCHOR_TYPE_START;
    case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER:
    case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER:
    case SsaStyle.SSA_ALIGNMENT_TOP_CENTER:
      return Cue.ANCHOR_TYPE_MIDDLE;
    case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT:
    case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT:
    case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT:
      return Cue.ANCHOR_TYPE_END;
    case SsaStyle.SSA_ALIGNMENT_UNKNOWN:
      return Cue.TYPE_UNSET;
    default:
      Log.w(TAG, "Unknown alignment: " + alignment);
      return Cue.TYPE_UNSET;
  }
}
 
Example #4
Source File: WebvttCueParser.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
private static void parseLineAttribute(String s, WebvttCue.Builder builder)
    throws NumberFormatException {
  int commaIndex = s.indexOf(',');
  if (commaIndex != -1) {
    builder.setLineAnchor(parsePositionAnchor(s.substring(commaIndex + 1)));
    s = s.substring(0, commaIndex);
  } else {
    builder.setLineAnchor(Cue.TYPE_UNSET);
  }
  if (s.endsWith("%")) {
    builder.setLine(WebvttParserUtil.parsePercentage(s)).setLineType(Cue.LINE_TYPE_FRACTION);
  } else {
    int lineNumber = Integer.parseInt(s);
    if (lineNumber < 0) {
      // WebVTT defines line -1 as last visible row when lineAnchor is ANCHOR_TYPE_START, where-as
      // Cue defines it to be the first row that's not visible.
      lineNumber--;
    }
    builder.setLine(lineNumber).setLineType(Cue.LINE_TYPE_NUMBER);
  }
}
 
Example #5
Source File: SsaDecoder.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
protected SsaSubtitle decode(byte[] bytes, int length, boolean reset) {
  ArrayList<Cue> cues = new ArrayList<>();
  LongArray cueTimesUs = new LongArray();

  ParsableByteArray data = new ParsableByteArray(bytes, length);
  if (!haveInitializationData) {
    parseHeader(data);
  }
  parseEventBody(data, cues, cueTimesUs);

  Cue[] cuesArray = new Cue[cues.size()];
  cues.toArray(cuesArray);
  long[] cueTimesUsArray = cueTimesUs.toArray();
  return new SsaSubtitle(cuesArray, cueTimesUsArray);
}
 
Example #6
Source File: WebvttCue.java    From K-Sonic with MIT License 6 votes vote down vote up
private Builder derivePositionAnchorFromAlignment() {
  if (textAlignment == null) {
    positionAnchor = Cue.TYPE_UNSET;
  } else {
    switch (textAlignment) {
      case ALIGN_NORMAL:
        positionAnchor = Cue.ANCHOR_TYPE_START;
        break;
      case ALIGN_CENTER:
        positionAnchor = Cue.ANCHOR_TYPE_MIDDLE;
        break;
      case ALIGN_OPPOSITE:
        positionAnchor = Cue.ANCHOR_TYPE_END;
        break;
      default:
        Log.w(TAG, "Unrecognized alignment: " + textAlignment);
        positionAnchor = Cue.ANCHOR_TYPE_START;
        break;
    }
  }
  return this;
}
 
Example #7
Source File: Mp4WebvttDecoder.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
protected Mp4WebvttSubtitle 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);
}
 
Example #8
Source File: SsaDecoder.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
protected SsaSubtitle decode(byte[] bytes, int length, boolean reset) {
  ArrayList<Cue> cues = new ArrayList<>();
  LongArray cueTimesUs = new LongArray();

  ParsableByteArray data = new ParsableByteArray(bytes, length);
  if (!haveInitializationData) {
    parseHeader(data);
  }
  parseEventBody(data, cues, cueTimesUs);

  Cue[] cuesArray = new Cue[cues.size()];
  cues.toArray(cuesArray);
  long[] cueTimesUsArray = cueTimesUs.toArray();
  return new SsaSubtitle(cuesArray, cueTimesUsArray);
}
 
Example #9
Source File: Mp4WebvttDecoder.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
private static Cue parseVttCueBox(ParsableByteArray sampleData, WebvttCue.Builder builder,
      int remainingCueBoxBytes) throws SubtitleDecoderException {
  builder.reset();
  while (remainingCueBoxBytes > 0) {
    if (remainingCueBoxBytes < BOX_HEADER_SIZE) {
      throw new SubtitleDecoderException("Incomplete vtt cue box header found.");
    }
    int boxSize = sampleData.readInt();
    int boxType = sampleData.readInt();
    remainingCueBoxBytes -= BOX_HEADER_SIZE;
    int payloadLength = boxSize - BOX_HEADER_SIZE;
    String boxPayload =
        Util.fromUtf8Bytes(sampleData.data, sampleData.getPosition(), payloadLength);
    sampleData.skipBytes(payloadLength);
    remainingCueBoxBytes -= payloadLength;
    if (boxType == TYPE_sttg) {
      WebvttCueParser.parseCueSettingsList(boxPayload, builder);
    } else if (boxType == TYPE_payl) {
      WebvttCueParser.parseCueText(null, boxPayload.trim(), builder, Collections.emptyList());
    } else {
      // Other VTTCueBox children are still not supported and are ignored.
    }
  }
  return builder.build();
}
 
Example #10
Source File: Mp4WebvttDecoder.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
@Override
protected Mp4WebvttSubtitle 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);
}
 
Example #11
Source File: PgsDecoder.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@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));
}
 
Example #12
Source File: PgsDecoder.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@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));
}
 
Example #13
Source File: Mp4WebvttDecoder.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
@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);
}
 
Example #14
Source File: WebvttCueParser.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
private static void parseLineAttribute(String s, WebvttCue.Builder builder)
    throws NumberFormatException {
  int commaIndex = s.indexOf(',');
  if (commaIndex != -1) {
    builder.setLineAnchor(parsePositionAnchor(s.substring(commaIndex + 1)));
    s = s.substring(0, commaIndex);
  } else {
    builder.setLineAnchor(Cue.TYPE_UNSET);
  }
  if (s.endsWith("%")) {
    builder.setLine(WebvttParserUtil.parsePercentage(s)).setLineType(Cue.LINE_TYPE_FRACTION);
  } else {
    int lineNumber = Integer.parseInt(s);
    if (lineNumber < 0) {
      // WebVTT defines line -1 as last visible row when lineAnchor is ANCHOR_TYPE_START, where-as
      // Cue defines it to be the first row that's not visible.
      lineNumber--;
    }
    builder.setLine(lineNumber).setLineType(Cue.LINE_TYPE_NUMBER);
  }
}
 
Example #15
Source File: WebvttCue.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
public WebvttCue build() {
  if (position != Cue.DIMEN_UNSET && positionAnchor == Cue.TYPE_UNSET) {
    derivePositionAnchorFromAlignment();
  }
  return new WebvttCue(startTime, endTime, text, textAlignment, line, lineType, lineAnchor,
      position, positionAnchor, width);
}
 
Example #16
Source File: SubripDecoder.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
static float getFractionalPositionForAnchorType(@Cue.AnchorType int anchorType) {
  switch (anchorType) {
    case Cue.ANCHOR_TYPE_START:
      return SubripDecoder.START_FRACTION;
    case Cue.ANCHOR_TYPE_MIDDLE:
      return SubripDecoder.MID_FRACTION;
    case Cue.ANCHOR_TYPE_END:
      return SubripDecoder.END_FRACTION;
    case Cue.TYPE_UNSET:
    default:
      // Should never happen.
      throw new IllegalArgumentException();
  }
}
 
Example #17
Source File: TtmlNode.java    From K-Sonic with MIT License 5 votes vote down vote up
public List<Cue> getCues(long timeUs, Map<String, TtmlStyle> globalStyles,
    Map<String, TtmlRegion> regionMap) {
  TreeMap<String, SpannableStringBuilder> regionOutputs = new TreeMap<>();
  traverseForText(timeUs, false, regionId, regionOutputs);
  traverseForStyle(globalStyles, regionOutputs);
  List<Cue> cues = new ArrayList<>();
  for (Entry<String, SpannableStringBuilder> entry : regionOutputs.entrySet()) {
    TtmlRegion region = regionMap.get(entry.getKey());
    cues.add(new Cue(cleanUpText(entry.getValue()), null, region.line, region.lineType,
        Cue.TYPE_UNSET, region.position, Cue.TYPE_UNSET, region.width));
  }
  return cues;
}
 
Example #18
Source File: SubripSubtitle.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@Override
public List<Cue> getCues(long timeUs) {
  int index = Util.binarySearchFloor(cueTimesUs, timeUs, true, false);
  if (index == -1 || cues[index] == Cue.EMPTY) {
    // timeUs is earlier than the start of the first cue, or we have an empty cue.
    return Collections.emptyList();
  } else {
    return Collections.singletonList(cues[index]);
  }
}
 
Example #19
Source File: Cea608Decoder.java    From K-Sonic with MIT License 5 votes vote down vote up
private List<Cue> getDisplayCues() {
  List<Cue> displayCues = new ArrayList<>();
  for (int i = 0; i < cueBuilders.size(); i++) {
    Cue cue = cueBuilders.get(i).build();
    if (cue != null) {
      displayCues.add(cue);
    }
  }
  return displayCues;
}
 
Example #20
Source File: WebvttCueParser.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private static void parsePositionAttribute(String s, WebvttCue.Builder builder)
    throws NumberFormatException {
  int commaIndex = s.indexOf(',');
  if (commaIndex != -1) {
    builder.setPositionAnchor(parsePositionAnchor(s.substring(commaIndex + 1)));
    s = s.substring(0, commaIndex);
  } else {
    builder.setPositionAnchor(Cue.TYPE_UNSET);
  }
  builder.setPosition(WebvttParserUtil.parsePercentage(s));
}
 
Example #21
Source File: WebvttCueParser.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static int parsePositionAnchor(String s) {
  switch (s) {
    case "start":
      return Cue.ANCHOR_TYPE_START;
    case "center":
    case "middle":
      return Cue.ANCHOR_TYPE_MIDDLE;
    case "end":
      return Cue.ANCHOR_TYPE_END;
    default:
      Log.w(TAG, "Invalid anchor value: " + s);
      return Cue.TYPE_UNSET;
  }
}
 
Example #22
Source File: WebvttCue.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
public WebvttCue(long startTime, long endTime, CharSequence text, Alignment textAlignment,
    float line, @Cue.LineType int lineType, @Cue.AnchorType int lineAnchor, float position,
    @Cue.AnchorType int positionAnchor, float width) {
  super(text, textAlignment, line, lineType, lineAnchor, position, positionAnchor, width);
  this.startTime = startTime;
  this.endTime = endTime;
}
 
Example #23
Source File: Tx3gDecoder.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@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));
}
 
Example #24
Source File: SubripSubtitle.java    From K-Sonic with MIT License 5 votes vote down vote up
@Override
public List<Cue> getCues(long timeUs) {
  int index = Util.binarySearchFloor(cueTimesUs, timeUs, true, false);
  if (index == -1 || cues[index] == null) {
    // timeUs is earlier than the start of the first cue, or we have an empty cue.
    return Collections.emptyList();
  } else {
    return Collections.singletonList(cues[index]);
  }
}
 
Example #25
Source File: SimpleExoPlayer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void onCues(List<Cue> cues) {
  currentCues = cues;
  for (TextOutput textOutput : textOutputs) {
    textOutput.onCues(cues);
  }
}
 
Example #26
Source File: WebvttCueParser.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static int parsePositionAnchor(String s) {
  switch (s) {
    case "start":
      return Cue.ANCHOR_TYPE_START;
    case "center":
    case "middle":
      return Cue.ANCHOR_TYPE_MIDDLE;
    case "end":
      return Cue.ANCHOR_TYPE_END;
    default:
      Log.w(TAG, "Invalid anchor value: " + s);
      return Cue.TYPE_UNSET;
  }
}
 
Example #27
Source File: SubripDecoder.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
static float getFractionalPositionForAnchorType(@Cue.AnchorType int anchorType) {
  switch (anchorType) {
    case Cue.ANCHOR_TYPE_START:
      return SubripDecoder.START_FRACTION;
    case Cue.ANCHOR_TYPE_MIDDLE:
      return SubripDecoder.MID_FRACTION;
    case Cue.ANCHOR_TYPE_END:
      return SubripDecoder.END_FRACTION;
    case Cue.TYPE_UNSET:
    default:
      // Should never happen.
      throw new IllegalArgumentException();
  }
}
 
Example #28
Source File: SubripSubtitle.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public List<Cue> getCues(long timeUs) {
  int index = Util.binarySearchFloor(cueTimesUs, timeUs, true, false);
  if (index == -1 || cues[index] == Cue.EMPTY) {
    // timeUs is earlier than the start of the first cue, or we have an empty cue.
    return Collections.emptyList();
  } else {
    return Collections.singletonList(cues[index]);
  }
}
 
Example #29
Source File: SimpleExoPlayer.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public void onCues(List<Cue> cues) {
  currentCues = cues;
  for (TextOutput textOutput : textOutputs) {
    textOutput.onCues(cues);
  }
}
 
Example #30
Source File: SsaSubtitle.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@Override
public List<Cue> getCues(long timeUs) {
  int index = Util.binarySearchFloor(cueTimesUs, timeUs, true, false);
  if (index == -1 || cues[index] == Cue.EMPTY) {
    // timeUs is earlier than the start of the first cue, or we have an empty cue.
    return Collections.emptyList();
  } else {
    return Collections.singletonList(cues[index]);
  }
}