mirror of
https://github.com/androidx/media.git
synced 2025-05-05 14:40:50 +08:00
Parse TLEN duration in Mp3Extractor
Issue: #7949 PiperOrigin-RevId: 333733615
This commit is contained in:
parent
19530866c7
commit
57f11d1556
@ -14,6 +14,8 @@
|
|||||||
* Extractors:
|
* Extractors:
|
||||||
* Add support for .mp2 boxes in the `AtomParsers`
|
* Add support for .mp2 boxes in the `AtomParsers`
|
||||||
([#7967](https://github.com/google/ExoPlayer/issues/7967)).
|
([#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) ###
|
### 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 firstFramePosition The position of the start of the first frame in the stream.
|
||||||
* @param mlltFrame The MLLT frame with seeking metadata.
|
* @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.
|
* @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;
|
int referenceCount = mlltFrame.bytesDeviations.length;
|
||||||
long[] referencePositions = new long[1 + referenceCount];
|
long[] referencePositions = new long[1 + referenceCount];
|
||||||
long[] referenceTimesMs = new long[1 + referenceCount];
|
long[] referenceTimesMs = new long[1 + referenceCount];
|
||||||
@ -45,19 +47,22 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
referencePositions[i] = position;
|
referencePositions[i] = position;
|
||||||
referenceTimesMs[i] = timeMs;
|
referenceTimesMs[i] = timeMs;
|
||||||
}
|
}
|
||||||
return new MlltSeeker(referencePositions, referenceTimesMs);
|
return new MlltSeeker(referencePositions, referenceTimesMs, durationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final long[] referencePositions;
|
private final long[] referencePositions;
|
||||||
private final long[] referenceTimesMs;
|
private final long[] referenceTimesMs;
|
||||||
private final long durationUs;
|
private final long durationUs;
|
||||||
|
|
||||||
private MlltSeeker(long[] referencePositions, long[] referenceTimesMs) {
|
private MlltSeeker(long[] referencePositions, long[] referenceTimesMs, long durationUs) {
|
||||||
this.referencePositions = referencePositions;
|
this.referencePositions = referencePositions;
|
||||||
this.referenceTimesMs = referenceTimesMs;
|
this.referenceTimesMs = referenceTimesMs;
|
||||||
// Use the last reference point as the duration, as extrapolating variable bitrate at the end of
|
// Use the last reference point as the duration if it is unknown, as extrapolating variable
|
||||||
// the stream may give a large error.
|
// bitrate at the end of the stream may give a large error.
|
||||||
durationUs = C.msToUs(referenceTimesMs[referenceTimesMs.length - 1]);
|
this.durationUs =
|
||||||
|
durationUs != C.TIME_UNSET
|
||||||
|
? durationUs
|
||||||
|
: C.msToUs(referenceTimesMs[referenceTimesMs.length - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
||||||
import com.google.android.exoplayer2.metadata.id3.Id3Decoder.FramePredicate;
|
import com.google.android.exoplayer2.metadata.id3.Id3Decoder.FramePredicate;
|
||||||
import com.google.android.exoplayer2.metadata.id3.MlltFrame;
|
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.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
@ -432,7 +433,7 @@ public final class Mp3Extractor implements Extractor {
|
|||||||
|
|
||||||
@Nullable Seeker resultSeeker = null;
|
@Nullable Seeker resultSeeker = null;
|
||||||
if ((flags & FLAG_ENABLE_INDEX_SEEKING) != 0) {
|
if ((flags & FLAG_ENABLE_INDEX_SEEKING) != 0) {
|
||||||
long durationUs = C.TIME_UNSET;
|
long durationUs;
|
||||||
long dataEndPosition = C.POSITION_UNSET;
|
long dataEndPosition = C.POSITION_UNSET;
|
||||||
if (metadataSeeker != null) {
|
if (metadataSeeker != null) {
|
||||||
durationUs = metadataSeeker.getDurationUs();
|
durationUs = metadataSeeker.getDurationUs();
|
||||||
@ -440,6 +441,8 @@ public final class Mp3Extractor implements Extractor {
|
|||||||
} else if (seekFrameSeeker != null) {
|
} else if (seekFrameSeeker != null) {
|
||||||
durationUs = seekFrameSeeker.getDurationUs();
|
durationUs = seekFrameSeeker.getDurationUs();
|
||||||
dataEndPosition = seekFrameSeeker.getDataEndPosition();
|
dataEndPosition = seekFrameSeeker.getDataEndPosition();
|
||||||
|
} else {
|
||||||
|
durationUs = getId3TlenUs(metadata);
|
||||||
}
|
}
|
||||||
resultSeeker =
|
resultSeeker =
|
||||||
new IndexSeeker(
|
new IndexSeeker(
|
||||||
@ -554,10 +557,24 @@ public final class Mp3Extractor implements Extractor {
|
|||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
Metadata.Entry entry = metadata.get(i);
|
Metadata.Entry entry = metadata.get(i);
|
||||||
if (entry instanceof MlltFrame) {
|
if (entry instanceof MlltFrame) {
|
||||||
return MlltSeeker.create(firstFramePosition, (MlltFrame) entry);
|
return MlltSeeker.create(firstFramePosition, (MlltFrame) entry, getId3TlenUs(metadata));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
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