diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 30ceb87a22..48976897bd 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -9,6 +9,8 @@ * ExoPlayer: * Add `FilteringMediaSource` that allows to filter available track types from a `MediaSource`. + * Fix bug seeking in files with long opus audio + ([#391](https://github.com/androidx/media/issues/391)). * Transformer: * Track Selection: * Extractors: diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ogg/DefaultOggSeeker.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ogg/DefaultOggSeeker.java index 2dfa232398..39d2214a9d 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ogg/DefaultOggSeeker.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ogg/DefaultOggSeeker.java @@ -28,6 +28,7 @@ import androidx.media3.extractor.SeekMap; import androidx.media3.extractor.SeekPoint; import java.io.EOFException; import java.io.IOException; +import java.math.BigInteger; /** Seeks in an Ogg stream. */ /* package */ final class DefaultOggSeeker implements OggSeeker { @@ -260,7 +261,12 @@ import java.io.IOException; long targetGranule = streamReader.convertTimeToGranule(timeUs); long estimatedPosition = payloadStartPosition - + (targetGranule * (payloadEndPosition - payloadStartPosition) / totalGranules) + // Use BigInteger arithmetic to avoid long overflow + // https://github.com/androidx/media/issues/391 + + BigInteger.valueOf(targetGranule) + .multiply(BigInteger.valueOf(payloadEndPosition - payloadStartPosition)) + .divide(BigInteger.valueOf(totalGranules)) + .longValue() - DEFAULT_OFFSET; estimatedPosition = Util.constrainValue(estimatedPosition, payloadStartPosition, payloadEndPosition - 1);