@Test public void testGetSeekPointsAtEndOfStream() { SeekPoints seekPoints = seeker.getSeekPoints(STREAM_DURATION_US); SeekPoint seekPoint = seekPoints.first; assertThat(seekPoint).isEqualTo(seekPoints.second); assertThat(seekPoint.timeUs).isEqualTo(STREAM_DURATION_US); assertThat(seekPoint.position).isEqualTo(STREAM_LENGTH - 1); }
@Override public SeekPoints getSeekPoints(long timeUs) { if (!isSeekable()) { return new SeekPoints(new SeekPoint(0, dataStartPosition + xingFrameSize)); } timeUs = Util.constrainValue(timeUs, 0, durationUs); double percent = (timeUs * 100d) / durationUs; double scaledPosition; if (percent <= 0) { scaledPosition = 0; } else if (percent >= 100) { scaledPosition = 256; } else { int prevTableIndex = (int) percent; long[] tableOfContents = Assertions.checkNotNull(this.tableOfContents); double prevScaledPosition = tableOfContents[prevTableIndex]; double nextScaledPosition = prevTableIndex == 99 ? 256 : tableOfContents[prevTableIndex + 1]; double interpolateFraction = percent - prevTableIndex; scaledPosition = prevScaledPosition + (interpolateFraction * (nextScaledPosition - prevScaledPosition)); } long positionOffset = Math.round((scaledPosition / 256) * dataSize); positionOffset = Util.constrainValue(positionOffset, xingFrameSize, dataSize - 1); return new SeekPoints(new SeekPoint(timeUs, dataStartPosition + positionOffset)); }
XingSeeker implements Mp3Extractor.Seeker { @Override public SeekPoints getSeekPoints(long timeUs) { if (!isSeekable()) { return new SeekPoints(new SeekPoint(0, dataStartPosition + xingFrameSize)); } timeUs = Util.constrainValue(timeUs, 0, durationUs); double percent = (timeUs * 100d) / durationUs; double scaledPosition; if (percent <= 0) { scaledPosition = 0; } else if (percent >= 100) { scaledPosition = 256; } else { int prevTableIndex = (int) percent; long[] tableOfContents = Assertions.checkNotNull(this.tableOfContents); double prevScaledPosition = tableOfContents[prevTableIndex]; double nextScaledPosition = prevTableIndex == 99 ? 256 : tableOfContents[prevTableIndex + 1]; double interpolateFraction = percent - prevTableIndex; scaledPosition = prevScaledPosition + (interpolateFraction * (nextScaledPosition - prevScaledPosition)); } long positionOffset = Math.round((scaledPosition / 256) * dataSize); positionOffset = Util.constrainValue(positionOffset, xingFrameSize, dataSize - 1); return new SeekPoints(new SeekPoint(timeUs, dataStartPosition + positionOffset)); } }
XingSeeker implements Mp3Extractor.Seeker { @Override public SeekPoints getSeekPoints(long timeUs) { if (!isSeekable()) { return new SeekPoints(new SeekPoint(0, dataStartPosition + xingFrameSize)); } timeUs = Util.constrainValue(timeUs, 0, durationUs); double percent = (timeUs * 100d) / durationUs; double scaledPosition; if (percent <= 0) { scaledPosition = 0; } else if (percent >= 100) { scaledPosition = 256; } else { int prevTableIndex = (int) percent; long[] tableOfContents = Assertions.checkNotNull(this.tableOfContents); double prevScaledPosition = tableOfContents[prevTableIndex]; double nextScaledPosition = prevTableIndex == 99 ? 256 : tableOfContents[prevTableIndex + 1]; double interpolateFraction = percent - prevTableIndex; scaledPosition = prevScaledPosition + (interpolateFraction * (nextScaledPosition - prevScaledPosition)); } long positionOffset = Math.round((scaledPosition / 256) * dataSize); positionOffset = Util.constrainValue(positionOffset, xingFrameSize, dataSize - 1); return new SeekPoints(new SeekPoint(timeUs, dataStartPosition + positionOffset)); } private  XingSeeker(long dataStartPosition, int xingFrameSize, long durationUs); private  XingSeeker(
      long dataStartPosition,
      int xingFrameSize,
      long durationUs,
      long dataSize,
      @Nullable long[] tableOfContents); }
XingSeeker implements Mp3Extractor.Seeker { @Override public SeekPoints getSeekPoints(long timeUs) { if (!isSeekable()) { return new SeekPoints(new SeekPoint(0, dataStartPosition + xingFrameSize)); } timeUs = Util.constrainValue(timeUs, 0, durationUs); double percent = (timeUs * 100d) / durationUs; double scaledPosition; if (percent <= 0) { scaledPosition = 0; } else if (percent >= 100) { scaledPosition = 256; } else { int prevTableIndex = (int) percent; long[] tableOfContents = Assertions.checkNotNull(this.tableOfContents); double prevScaledPosition = tableOfContents[prevTableIndex]; double nextScaledPosition = prevTableIndex == 99 ? 256 : tableOfContents[prevTableIndex + 1]; double interpolateFraction = percent - prevTableIndex; scaledPosition = prevScaledPosition + (interpolateFraction * (nextScaledPosition - prevScaledPosition)); } long positionOffset = Math.round((scaledPosition / 256) * dataSize); positionOffset = Util.constrainValue(positionOffset, xingFrameSize, dataSize - 1); return new SeekPoints(new SeekPoint(timeUs, dataStartPosition + positionOffset)); } private  XingSeeker(long dataStartPosition, int xingFrameSize, long durationUs); private  XingSeeker(
      long dataStartPosition,
      int xingFrameSize,
      long durationUs,
      long dataSize,
      @Nullable long[] tableOfContents); static @Nullable XingSeeker create(
      long inputLength, long position, MpegAudioHeader mpegAudioHeader, ParsableByteArray frame); @Override boolean isSeekable(); @Override SeekPoints getSeekPoints(long timeUs); @Override long getTimeUs(long position); @Override long getDurationUs(); @Override long getDataEndPosition(); }
XingSeeker implements Mp3Extractor.Seeker { @Override public SeekPoints getSeekPoints(long timeUs) { if (!isSeekable()) { return new SeekPoints(new SeekPoint(0, dataStartPosition + xingFrameSize)); } timeUs = Util.constrainValue(timeUs, 0, durationUs); double percent = (timeUs * 100d) / durationUs; double scaledPosition; if (percent <= 0) { scaledPosition = 0; } else if (percent >= 100) { scaledPosition = 256; } else { int prevTableIndex = (int) percent; long[] tableOfContents = Assertions.checkNotNull(this.tableOfContents); double prevScaledPosition = tableOfContents[prevTableIndex]; double nextScaledPosition = prevTableIndex == 99 ? 256 : tableOfContents[prevTableIndex + 1]; double interpolateFraction = percent - prevTableIndex; scaledPosition = prevScaledPosition + (interpolateFraction * (nextScaledPosition - prevScaledPosition)); } long positionOffset = Math.round((scaledPosition / 256) * dataSize); positionOffset = Util.constrainValue(positionOffset, xingFrameSize, dataSize - 1); return new SeekPoints(new SeekPoint(timeUs, dataStartPosition + positionOffset)); } private  XingSeeker(long dataStartPosition, int xingFrameSize, long durationUs); private  XingSeeker(
      long dataStartPosition,
      int xingFrameSize,
      long durationUs,
      long dataSize,
      @Nullable long[] tableOfContents); static @Nullable XingSeeker create(
      long inputLength, long position, MpegAudioHeader mpegAudioHeader, ParsableByteArray frame); @Override boolean isSeekable(); @Override SeekPoints getSeekPoints(long timeUs); @Override long getTimeUs(long position); @Override long getDurationUs(); @Override long getDataEndPosition();  }