Skip to content

Commit

Permalink
Parse TLEN duration in Mp3Extractor
Browse files Browse the repository at this point in the history
Issue: #7949
PiperOrigin-RevId: 333733615
  • Loading branch information
kim-vde authored and ojw28 committed Oct 17, 2020
1 parent 1953086 commit 57f11d1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* Extractors:
* Add support for .mp2 boxes in the `AtomParsers`
([#7967](https://github.com/google/ExoPlayer/issues/7967)).
* Use TLEN ID3 tag to compute the duration in Mp3Extractor
([#7949](https://github.com/google/ExoPlayer/issues/7949)).

### 2.12.0 (2020-09-11) ###

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
*
* @param firstFramePosition The position of the start of the first frame in the stream.
* @param mlltFrame The MLLT frame with seeking metadata.
* @param durationUs The stream duration in microseconds, or {@link C#TIME_UNSET} if it is
* unknown.
* @return An {@link MlltSeeker} for seeking in the stream.
*/
public static MlltSeeker create(long firstFramePosition, MlltFrame mlltFrame) {
public static MlltSeeker create(long firstFramePosition, MlltFrame mlltFrame, long durationUs) {
int referenceCount = mlltFrame.bytesDeviations.length;
long[] referencePositions = new long[1 + referenceCount];
long[] referenceTimesMs = new long[1 + referenceCount];
Expand All @@ -45,19 +47,22 @@ public static MlltSeeker create(long firstFramePosition, MlltFrame mlltFrame) {
referencePositions[i] = position;
referenceTimesMs[i] = timeMs;
}
return new MlltSeeker(referencePositions, referenceTimesMs);
return new MlltSeeker(referencePositions, referenceTimesMs, durationUs);
}

private final long[] referencePositions;
private final long[] referenceTimesMs;
private final long durationUs;

private MlltSeeker(long[] referencePositions, long[] referenceTimesMs) {
private MlltSeeker(long[] referencePositions, long[] referenceTimesMs, long durationUs) {
this.referencePositions = referencePositions;
this.referenceTimesMs = referenceTimesMs;
// Use the last reference point as the duration, as extrapolating variable bitrate at the end of
// the stream may give a large error.
durationUs = C.msToUs(referenceTimesMs[referenceTimesMs.length - 1]);
// Use the last reference point as the duration if it is unknown, as extrapolating variable
// bitrate at the end of the stream may give a large error.
this.durationUs =
durationUs != C.TIME_UNSET
? durationUs
: C.msToUs(referenceTimesMs[referenceTimesMs.length - 1]);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.google.android.exoplayer2.metadata.id3.Id3Decoder;
import com.google.android.exoplayer2.metadata.id3.Id3Decoder.FramePredicate;
import com.google.android.exoplayer2.metadata.id3.MlltFrame;
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
Expand Down Expand Up @@ -432,14 +433,16 @@ private Seeker computeSeeker(ExtractorInput input) throws IOException {

@Nullable Seeker resultSeeker = null;
if ((flags & FLAG_ENABLE_INDEX_SEEKING) != 0) {
long durationUs = C.TIME_UNSET;
long durationUs;
long dataEndPosition = C.POSITION_UNSET;
if (metadataSeeker != null) {
durationUs = metadataSeeker.getDurationUs();
dataEndPosition = metadataSeeker.getDataEndPosition();
} else if (seekFrameSeeker != null) {
durationUs = seekFrameSeeker.getDurationUs();
dataEndPosition = seekFrameSeeker.getDataEndPosition();
} else {
durationUs = getId3TlenUs(metadata);
}
resultSeeker =
new IndexSeeker(
Expand Down Expand Up @@ -554,10 +557,24 @@ private static MlltSeeker maybeHandleSeekMetadata(
for (int i = 0; i < length; i++) {
Metadata.Entry entry = metadata.get(i);
if (entry instanceof MlltFrame) {
return MlltSeeker.create(firstFramePosition, (MlltFrame) entry);
return MlltSeeker.create(firstFramePosition, (MlltFrame) entry, getId3TlenUs(metadata));
}
}
}
return null;
}

private static long getId3TlenUs(@Nullable Metadata metadata) {
if (metadata != null) {
int length = metadata.length();
for (int i = 0; i < length; i++) {
Metadata.Entry entry = metadata.get(i);
if (entry instanceof TextInformationFrame
&& ((TextInformationFrame) entry).id.equals("TLEN")) {
return C.msToUs(Long.parseLong(((TextInformationFrame) entry).value));
}
}
}
return C.TIME_UNSET;
}
}

0 comments on commit 57f11d1

Please sign in to comment.