Parse TLEN duration in Mp3Extractor
Issue: #7949 PiperOrigin-RevId: 333733615
This commit is contained in:
parent
19530866c7
commit
57f11d1556
@ -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) ###
|
||||
|
||||
|
@ -29,9 +29,11 @@ import com.google.android.exoplayer2.util.Util;
|
||||
*
|
||||
* @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];
|
||||
@ -45,19 +47,22 @@ import com.google.android.exoplayer2.util.Util;
|
||||
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
|
||||
|
@ -35,6 +35,7 @@ import com.google.android.exoplayer2.metadata.Metadata;
|
||||
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;
|
||||
@ -432,7 +433,7 @@ public final class Mp3Extractor implements Extractor {
|
||||
|
||||
@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();
|
||||
@ -440,6 +441,8 @@ public final class Mp3Extractor implements Extractor {
|
||||
} else if (seekFrameSeeker != null) {
|
||||
durationUs = seekFrameSeeker.getDurationUs();
|
||||
dataEndPosition = seekFrameSeeker.getDataEndPosition();
|
||||
} else {
|
||||
durationUs = getId3TlenUs(metadata);
|
||||
}
|
||||
resultSeeker =
|
||||
new IndexSeeker(
|
||||
@ -554,10 +557,24 @@ public final class Mp3Extractor implements Extractor {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user