diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/SeekMap.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/SeekMap.java index 778aa4d715..964c43a45a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/SeekMap.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/SeekMap.java @@ -28,13 +28,24 @@ public interface SeekMap { final class Unseekable implements SeekMap { private final long durationUs; + private final long startPosition; /** * @param durationUs The duration of the stream in microseconds, or {@link C#TIME_UNSET} if * the duration is unknown. */ public Unseekable(long durationUs) { + this(durationUs, 0); + } + + /** + * @param durationUs The duration of the stream in microseconds, or {@link C#TIME_UNSET} if + * the duration is unknown. + * @param startPosition The position (byte offset) of the start of the media. + */ + public Unseekable(long durationUs, long startPosition) { this.durationUs = durationUs; + this.startPosition = startPosition; } @Override @@ -49,7 +60,7 @@ public interface SeekMap { @Override public long getPosition(long timeUs) { - return 0; + return startPosition; } } @@ -78,7 +89,8 @@ public interface SeekMap { * * @param timeUs A seek position in microseconds. * @return The corresponding position (byte offset) in the stream from which data can be provided - * to the extractor, or 0 if {@code #isSeekable()} returns false. + * to the extractor. If {@link #isSeekable()} returns false then the returned value will be + * independent of {@code timeUs}, and will indicate the start of the media in the stream. */ long getPosition(long timeUs); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp3/ConstantBitrateSeeker.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp3/ConstantBitrateSeeker.java index df7748a910..47e12161a8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp3/ConstantBitrateSeeker.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp3/ConstantBitrateSeeker.java @@ -43,7 +43,7 @@ import com.google.android.exoplayer2.util.Util; @Override public long getPosition(long timeUs) { if (durationUs == C.TIME_UNSET) { - return 0; + return firstFramePosition; } timeUs = Util.constrainValue(timeUs, 0, durationUs); return firstFramePosition + (timeUs * bitrate) / (C.MICROS_PER_SECOND * BITS_PER_BYTE); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index 4bc1b04418..28a1ffaa7b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -345,7 +345,8 @@ public final class FragmentedMp4Extractor implements Extractor { currentTrackBundle = null; endOfMdatPosition = atomPosition + atomSize; if (!haveOutputSeekMap) { - extractorOutput.seekMap(new SeekMap.Unseekable(durationUs)); + // This must be the first mdat in the stream. + extractorOutput.seekMap(new SeekMap.Unseekable(durationUs, atomPosition)); haveOutputSeekMap = true; } parserState = STATE_READING_ENCRYPTION_DATA;