mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
Add IndexSeeker to MP3 extractor
This seeker is only seeking to frames that have already been read by the extractor for playback. Seeking to not-yet-read frames will be implemented in another change. Issue: #6787 PiperOrigin-RevId: 291888899
This commit is contained in:
parent
bb9b3fd45e
commit
103bd4199c
8 changed files with 1241 additions and 7 deletions
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.extractor.mp3;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.extractor.SeekPoint;
|
||||
import com.google.android.exoplayer2.util.LongArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/** MP3 seeker that builds a time-to-byte mapping as the stream is read. */
|
||||
/* package */ final class IndexSeeker implements Seeker {
|
||||
|
||||
private static final long MIN_TIME_BETWEEN_POINTS_US = C.MICROS_PER_SECOND / 10;
|
||||
|
||||
private final long durationUs;
|
||||
private final long dataEndPosition;
|
||||
private final LongArray timesUs;
|
||||
private final LongArray positions;
|
||||
|
||||
public IndexSeeker(long durationUs, long dataStartPosition, long dataEndPosition) {
|
||||
this.durationUs = durationUs;
|
||||
this.dataEndPosition = dataEndPosition;
|
||||
timesUs = new LongArray();
|
||||
positions = new LongArray();
|
||||
timesUs.add(0L);
|
||||
positions.add(dataStartPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeUs(long position) {
|
||||
int targetIndex =
|
||||
Util.binarySearchFloor(
|
||||
positions, position, /* inclusive= */ true, /* stayInBounds= */ true);
|
||||
return timesUs.get(targetIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataEndPosition() {
|
||||
return dataEndPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSeekable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDurationUs() {
|
||||
return durationUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeekPoints getSeekPoints(long timeUs) {
|
||||
int targetIndex =
|
||||
Util.binarySearchFloor(timesUs, timeUs, /* inclusive= */ true, /* stayInBounds= */ true);
|
||||
SeekPoint seekPoint = new SeekPoint(timesUs.get(targetIndex), positions.get(targetIndex));
|
||||
if (seekPoint.timeUs >= timeUs || targetIndex == timesUs.size() - 1) {
|
||||
return new SeekPoints(seekPoint);
|
||||
} else {
|
||||
SeekPoint nextSeekPoint =
|
||||
new SeekPoint(timesUs.get(targetIndex + 1), positions.get(targetIndex + 1));
|
||||
return new SeekPoints(seekPoint, nextSeekPoint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a seek point to the index if it is sufficiently distant from the other points.
|
||||
*
|
||||
* <p>Seek points must be added in order.
|
||||
*
|
||||
* @param timeUs The time corresponding to the seek point to add in microseconds.
|
||||
* @param position The position corresponding to the seek point to add in bytes.
|
||||
*/
|
||||
public void maybeAddSeekPoint(long timeUs, long position) {
|
||||
long lastTimeUs = timesUs.get(timesUs.size() - 1);
|
||||
if (timeUs - lastTimeUs < MIN_TIME_BETWEEN_POINTS_US) {
|
||||
return;
|
||||
}
|
||||
timesUs.add(timeUs);
|
||||
positions.add(position);
|
||||
}
|
||||
}
|
||||
|
|
@ -56,24 +56,35 @@ public final class Mp3Extractor implements Extractor {
|
|||
|
||||
/**
|
||||
* Flags controlling the behavior of the extractor. Possible flag values are {@link
|
||||
* #FLAG_ENABLE_CONSTANT_BITRATE_SEEKING} and {@link #FLAG_DISABLE_ID3_METADATA}.
|
||||
* #FLAG_ENABLE_CONSTANT_BITRATE_SEEKING}, {@link #FLAG_ENABLE_INDEX_SEEKING} and {@link
|
||||
* #FLAG_DISABLE_ID3_METADATA}.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(
|
||||
flag = true,
|
||||
value = {FLAG_ENABLE_CONSTANT_BITRATE_SEEKING, FLAG_DISABLE_ID3_METADATA})
|
||||
value = {
|
||||
FLAG_ENABLE_CONSTANT_BITRATE_SEEKING,
|
||||
FLAG_ENABLE_INDEX_SEEKING,
|
||||
FLAG_DISABLE_ID3_METADATA
|
||||
})
|
||||
public @interface Flags {}
|
||||
/**
|
||||
* Flag to force enable seeking using a constant bitrate assumption in cases where seeking would
|
||||
* otherwise not be possible.
|
||||
*
|
||||
* <p>This flag is ignored if {@link #FLAG_ENABLE_INDEX_SEEKING} is set.
|
||||
*/
|
||||
public static final int FLAG_ENABLE_CONSTANT_BITRATE_SEEKING = 1;
|
||||
/**
|
||||
* Flag to force index seeking, consisting in building a time-to-byte mapping as the file is read.
|
||||
*/
|
||||
public static final int FLAG_ENABLE_INDEX_SEEKING = 1 << 1;
|
||||
/**
|
||||
* Flag to disable parsing of ID3 metadata. Can be set to save memory if ID3 metadata is not
|
||||
* required.
|
||||
*/
|
||||
public static final int FLAG_DISABLE_ID3_METADATA = 2;
|
||||
public static final int FLAG_DISABLE_ID3_METADATA = 1 << 2;
|
||||
|
||||
/** Predicate that matches ID3 frames containing only required gapless/seeking metadata. */
|
||||
private static final FramePredicate REQUIRED_ID3_FRAME_PREDICATE =
|
||||
|
|
@ -256,6 +267,9 @@ public final class Mp3Extractor implements Extractor {
|
|||
}
|
||||
}
|
||||
sampleBytesRemaining = synchronizedHeader.frameSize;
|
||||
maybeAddSeekPointToIndexSeeker(
|
||||
computeTimeUs(samplesRead + synchronizedHeader.samplesPerFrame),
|
||||
extractorInput.getPosition() + synchronizedHeader.frameSize);
|
||||
}
|
||||
int bytesAppended = trackOutput.sampleData(extractorInput, sampleBytesRemaining, true);
|
||||
if (bytesAppended == C.RESULT_END_OF_INPUT) {
|
||||
|
|
@ -265,14 +279,24 @@ public final class Mp3Extractor implements Extractor {
|
|||
if (sampleBytesRemaining > 0) {
|
||||
return RESULT_CONTINUE;
|
||||
}
|
||||
long timeUs = basisTimeUs + (samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate);
|
||||
trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, synchronizedHeader.frameSize, 0,
|
||||
null);
|
||||
trackOutput.sampleMetadata(
|
||||
computeTimeUs(samplesRead), C.BUFFER_FLAG_KEY_FRAME, synchronizedHeader.frameSize, 0, null);
|
||||
samplesRead += synchronizedHeader.samplesPerFrame;
|
||||
sampleBytesRemaining = 0;
|
||||
return RESULT_CONTINUE;
|
||||
}
|
||||
|
||||
private long computeTimeUs(long samplesRead) {
|
||||
return basisTimeUs + samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate;
|
||||
}
|
||||
|
||||
private void maybeAddSeekPointToIndexSeeker(long timeUs, long position) {
|
||||
if (!(seeker instanceof IndexSeeker)) {
|
||||
return;
|
||||
}
|
||||
((IndexSeeker) seeker).maybeAddSeekPoint(timeUs, position);
|
||||
}
|
||||
|
||||
private boolean synchronize(ExtractorInput input, boolean sniffing)
|
||||
throws IOException, InterruptedException {
|
||||
int validFrameCount = 0;
|
||||
|
|
@ -379,7 +403,20 @@ public final class Mp3Extractor implements Extractor {
|
|||
}
|
||||
|
||||
@Nullable Seeker resultSeeker = null;
|
||||
if (metadataSeeker != null) {
|
||||
if ((flags & FLAG_ENABLE_INDEX_SEEKING) != 0) {
|
||||
long durationUs = C.TIME_UNSET;
|
||||
long dataEndPosition = C.POSITION_UNSET;
|
||||
if (metadataSeeker != null) {
|
||||
durationUs = metadataSeeker.getDurationUs();
|
||||
dataEndPosition = metadataSeeker.getDataEndPosition();
|
||||
} else if (seekFrameSeeker != null) {
|
||||
durationUs = seekFrameSeeker.getDurationUs();
|
||||
dataEndPosition = seekFrameSeeker.getDataEndPosition();
|
||||
}
|
||||
resultSeeker =
|
||||
new IndexSeeker(
|
||||
durationUs, /* dataStartPosition= */ input.getPosition(), dataEndPosition);
|
||||
} else if (metadataSeeker != null) {
|
||||
resultSeeker = metadataSeeker;
|
||||
} else if (seekFrameSeeker != null) {
|
||||
resultSeeker = seekFrameSeeker;
|
||||
|
|
|
|||
BIN
library/extractor/src/test/assets/mp3/bear-vbr.mp3
Normal file
BIN
library/extractor/src/test/assets/mp3/bear-vbr.mp3
Normal file
Binary file not shown.
499
library/extractor/src/test/assets/mp3/bear-vbr.mp3.0.dump
Normal file
499
library/extractor/src/test/assets/mp3/bear-vbr.mp3.0.dump
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2808000
|
||||
getPosition(0) = [[timeUs=0, position=237]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
format:
|
||||
bitrate = -1
|
||||
id = null
|
||||
containerMimeType = null
|
||||
sampleMimeType = audio/mpeg
|
||||
maxInputSize = 4096
|
||||
width = -1
|
||||
height = -1
|
||||
frameRate = -1.0
|
||||
rotationDegrees = 0
|
||||
pixelWidthHeightRatio = 1.0
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
pcmEncoding = -1
|
||||
encoderDelay = 576
|
||||
encoderPadding = 576
|
||||
subsampleOffsetUs = 9223372036854775807
|
||||
selectionFlags = 0
|
||||
language = null
|
||||
drmInitData = -
|
||||
metadata = entries=[TSSE: description=null: value=Lavf58.29.100]
|
||||
initializationData:
|
||||
total output bytes = 38160
|
||||
sample count = 117
|
||||
sample 0:
|
||||
time = 0
|
||||
flags = 1
|
||||
data = length 96, hash 1F161542
|
||||
sample 1:
|
||||
time = 24000
|
||||
flags = 1
|
||||
data = length 768, hash CD1DC50F
|
||||
sample 2:
|
||||
time = 48000
|
||||
flags = 1
|
||||
data = length 336, hash 3F64124B
|
||||
sample 3:
|
||||
time = 72000
|
||||
flags = 1
|
||||
data = length 336, hash 8FFED94E
|
||||
sample 4:
|
||||
time = 96000
|
||||
flags = 1
|
||||
data = length 288, hash 9CD77D47
|
||||
sample 5:
|
||||
time = 120000
|
||||
flags = 1
|
||||
data = length 384, hash 24607BB5
|
||||
sample 6:
|
||||
time = 144000
|
||||
flags = 1
|
||||
data = length 480, hash 4937EBAB
|
||||
sample 7:
|
||||
time = 168000
|
||||
flags = 1
|
||||
data = length 336, hash 546342B1
|
||||
sample 8:
|
||||
time = 192000
|
||||
flags = 1
|
||||
data = length 336, hash 79E0923F
|
||||
sample 9:
|
||||
time = 216000
|
||||
flags = 1
|
||||
data = length 336, hash AB1F3948
|
||||
sample 10:
|
||||
time = 240000
|
||||
flags = 1
|
||||
data = length 336, hash C3A4D888
|
||||
sample 11:
|
||||
time = 264000
|
||||
flags = 1
|
||||
data = length 288, hash 7867DA45
|
||||
sample 12:
|
||||
time = 288000
|
||||
flags = 1
|
||||
data = length 336, hash B1240B73
|
||||
sample 13:
|
||||
time = 312000
|
||||
flags = 1
|
||||
data = length 336, hash 94CFCD35
|
||||
sample 14:
|
||||
time = 336000
|
||||
flags = 1
|
||||
data = length 288, hash 94F412C
|
||||
sample 15:
|
||||
time = 360000
|
||||
flags = 1
|
||||
data = length 336, hash A1D9FF41
|
||||
sample 16:
|
||||
time = 384000
|
||||
flags = 1
|
||||
data = length 288, hash 2A8DA21B
|
||||
sample 17:
|
||||
time = 408000
|
||||
flags = 1
|
||||
data = length 336, hash 6A429CE
|
||||
sample 18:
|
||||
time = 432000
|
||||
flags = 1
|
||||
data = length 336, hash 68853982
|
||||
sample 19:
|
||||
time = 456000
|
||||
flags = 1
|
||||
data = length 384, hash 1D6F779C
|
||||
sample 20:
|
||||
time = 480000
|
||||
flags = 1
|
||||
data = length 480, hash 6B31EBEE
|
||||
sample 21:
|
||||
time = 504000
|
||||
flags = 1
|
||||
data = length 336, hash 888335BE
|
||||
sample 22:
|
||||
time = 528000
|
||||
flags = 1
|
||||
data = length 336, hash 6072AC8B
|
||||
sample 23:
|
||||
time = 552000
|
||||
flags = 1
|
||||
data = length 336, hash C9D24234
|
||||
sample 24:
|
||||
time = 576000
|
||||
flags = 1
|
||||
data = length 288, hash 52BF4D1E
|
||||
sample 25:
|
||||
time = 600000
|
||||
flags = 1
|
||||
data = length 336, hash F93F4F0
|
||||
sample 26:
|
||||
time = 624000
|
||||
flags = 1
|
||||
data = length 336, hash 8617688A
|
||||
sample 27:
|
||||
time = 648000
|
||||
flags = 1
|
||||
data = length 480, hash FAB0D31B
|
||||
sample 28:
|
||||
time = 672000
|
||||
flags = 1
|
||||
data = length 384, hash FA4B53E2
|
||||
sample 29:
|
||||
time = 696000
|
||||
flags = 1
|
||||
data = length 336, hash 8C435F6A
|
||||
sample 30:
|
||||
time = 720000
|
||||
flags = 1
|
||||
data = length 336, hash 60D3F80C
|
||||
sample 31:
|
||||
time = 744000
|
||||
flags = 1
|
||||
data = length 336, hash DC15B68B
|
||||
sample 32:
|
||||
time = 768000
|
||||
flags = 1
|
||||
data = length 288, hash FF3DF141
|
||||
sample 33:
|
||||
time = 792000
|
||||
flags = 1
|
||||
data = length 336, hash A64B3042
|
||||
sample 34:
|
||||
time = 816000
|
||||
flags = 1
|
||||
data = length 336, hash ACA622A1
|
||||
sample 35:
|
||||
time = 840000
|
||||
flags = 1
|
||||
data = length 288, hash 3E34B8D4
|
||||
sample 36:
|
||||
time = 864000
|
||||
flags = 1
|
||||
data = length 288, hash 9B96F72A
|
||||
sample 37:
|
||||
time = 888000
|
||||
flags = 1
|
||||
data = length 336, hash E917C122
|
||||
sample 38:
|
||||
time = 912000
|
||||
flags = 1
|
||||
data = length 336, hash 10ED1470
|
||||
sample 39:
|
||||
time = 936000
|
||||
flags = 1
|
||||
data = length 288, hash 706B8A7C
|
||||
sample 40:
|
||||
time = 960000
|
||||
flags = 1
|
||||
data = length 336, hash 71FFE4A0
|
||||
sample 41:
|
||||
time = 984000
|
||||
flags = 1
|
||||
data = length 336, hash D4160463
|
||||
sample 42:
|
||||
time = 1008000
|
||||
flags = 1
|
||||
data = length 336, hash EC557B14
|
||||
sample 43:
|
||||
time = 1032000
|
||||
flags = 1
|
||||
data = length 288, hash 5598CF8B
|
||||
sample 44:
|
||||
time = 1056000
|
||||
flags = 1
|
||||
data = length 336, hash 7E0AB41
|
||||
sample 45:
|
||||
time = 1080000
|
||||
flags = 1
|
||||
data = length 336, hash 1C585FEF
|
||||
sample 46:
|
||||
time = 1104000
|
||||
flags = 1
|
||||
data = length 336, hash A4A4855E
|
||||
sample 47:
|
||||
time = 1128000
|
||||
flags = 1
|
||||
data = length 336, hash CECA51D3
|
||||
sample 48:
|
||||
time = 1152000
|
||||
flags = 1
|
||||
data = length 288, hash 2D362DC5
|
||||
sample 49:
|
||||
time = 1176000
|
||||
flags = 1
|
||||
data = length 336, hash 9EB2609D
|
||||
sample 50:
|
||||
time = 1200000
|
||||
flags = 1
|
||||
data = length 336, hash 28FFB3FE
|
||||
sample 51:
|
||||
time = 1224000
|
||||
flags = 1
|
||||
data = length 288, hash 2AA2D216
|
||||
sample 52:
|
||||
time = 1248000
|
||||
flags = 1
|
||||
data = length 336, hash CDBC7032
|
||||
sample 53:
|
||||
time = 1272000
|
||||
flags = 1
|
||||
data = length 336, hash 25B13FE7
|
||||
sample 54:
|
||||
time = 1296000
|
||||
flags = 1
|
||||
data = length 336, hash DB6BB1E
|
||||
sample 55:
|
||||
time = 1320000
|
||||
flags = 1
|
||||
data = length 336, hash EBE951F4
|
||||
sample 56:
|
||||
time = 1344000
|
||||
flags = 1
|
||||
data = length 288, hash 9E2EBFF7
|
||||
sample 57:
|
||||
time = 1368000
|
||||
flags = 1
|
||||
data = length 336, hash 36A7D455
|
||||
sample 58:
|
||||
time = 1392000
|
||||
flags = 1
|
||||
data = length 336, hash 84545F8C
|
||||
sample 59:
|
||||
time = 1416000
|
||||
flags = 1
|
||||
data = length 336, hash F66F3045
|
||||
sample 60:
|
||||
time = 1440000
|
||||
flags = 1
|
||||
data = length 576, hash 5AB089EA
|
||||
sample 61:
|
||||
time = 1464000
|
||||
flags = 1
|
||||
data = length 336, hash 8868086
|
||||
sample 62:
|
||||
time = 1488000
|
||||
flags = 1
|
||||
data = length 336, hash D5EB6D63
|
||||
sample 63:
|
||||
time = 1512000
|
||||
flags = 1
|
||||
data = length 288, hash 7A5374B7
|
||||
sample 64:
|
||||
time = 1536000
|
||||
flags = 1
|
||||
data = length 336, hash BEB27A75
|
||||
sample 65:
|
||||
time = 1560000
|
||||
flags = 1
|
||||
data = length 336, hash E251E0FD
|
||||
sample 66:
|
||||
time = 1584000
|
||||
flags = 1
|
||||
data = length 288, hash D54C970
|
||||
sample 67:
|
||||
time = 1608000
|
||||
flags = 1
|
||||
data = length 336, hash 52C473B9
|
||||
sample 68:
|
||||
time = 1632000
|
||||
flags = 1
|
||||
data = length 336, hash F5F13334
|
||||
sample 69:
|
||||
time = 1656000
|
||||
flags = 1
|
||||
data = length 480, hash A5F1E987
|
||||
sample 70:
|
||||
time = 1680000
|
||||
flags = 1
|
||||
data = length 288, hash 453A1267
|
||||
sample 71:
|
||||
time = 1704000
|
||||
flags = 1
|
||||
data = length 288, hash 7C6C2EA9
|
||||
sample 72:
|
||||
time = 1728000
|
||||
flags = 1
|
||||
data = length 336, hash F4BFECA4
|
||||
sample 73:
|
||||
time = 1752000
|
||||
flags = 1
|
||||
data = length 336, hash 751A395A
|
||||
sample 74:
|
||||
time = 1776000
|
||||
flags = 1
|
||||
data = length 336, hash EE38DB02
|
||||
sample 75:
|
||||
time = 1800000
|
||||
flags = 1
|
||||
data = length 336, hash F18837E2
|
||||
sample 76:
|
||||
time = 1824000
|
||||
flags = 1
|
||||
data = length 336, hash ED36B78E
|
||||
sample 77:
|
||||
time = 1848000
|
||||
flags = 1
|
||||
data = length 336, hash B3D28289
|
||||
sample 78:
|
||||
time = 1872000
|
||||
flags = 1
|
||||
data = length 288, hash 8BDE28E1
|
||||
sample 79:
|
||||
time = 1896000
|
||||
flags = 1
|
||||
data = length 336, hash CFD5E966
|
||||
sample 80:
|
||||
time = 1920000
|
||||
flags = 1
|
||||
data = length 288, hash DC08E267
|
||||
sample 81:
|
||||
time = 1944000
|
||||
flags = 1
|
||||
data = length 336, hash 6530CB78
|
||||
sample 82:
|
||||
time = 1968000
|
||||
flags = 1
|
||||
data = length 336, hash 6CC6636E
|
||||
sample 83:
|
||||
time = 1992000
|
||||
flags = 1
|
||||
data = length 336, hash 613047C1
|
||||
sample 84:
|
||||
time = 2016000
|
||||
flags = 1
|
||||
data = length 288, hash CDC747BF
|
||||
sample 85:
|
||||
time = 2040000
|
||||
flags = 1
|
||||
data = length 336, hash AF22AA74
|
||||
sample 86:
|
||||
time = 2064000
|
||||
flags = 1
|
||||
data = length 384, hash 82F326AA
|
||||
sample 87:
|
||||
time = 2088000
|
||||
flags = 1
|
||||
data = length 384, hash EDA26C4D
|
||||
sample 88:
|
||||
time = 2112000
|
||||
flags = 1
|
||||
data = length 336, hash 94C643DC
|
||||
sample 89:
|
||||
time = 2136000
|
||||
flags = 1
|
||||
data = length 288, hash CB5D9C40
|
||||
sample 90:
|
||||
time = 2160000
|
||||
flags = 1
|
||||
data = length 336, hash 1E69DE3F
|
||||
sample 91:
|
||||
time = 2184000
|
||||
flags = 1
|
||||
data = length 336, hash 7E472219
|
||||
sample 92:
|
||||
time = 2208000
|
||||
flags = 1
|
||||
data = length 336, hash DA47B9FA
|
||||
sample 93:
|
||||
time = 2232000
|
||||
flags = 1
|
||||
data = length 336, hash DD0ABB7C
|
||||
sample 94:
|
||||
time = 2256000
|
||||
flags = 1
|
||||
data = length 288, hash DBF93FAC
|
||||
sample 95:
|
||||
time = 2280000
|
||||
flags = 1
|
||||
data = length 336, hash 243F4B2
|
||||
sample 96:
|
||||
time = 2304000
|
||||
flags = 1
|
||||
data = length 336, hash 2E881490
|
||||
sample 97:
|
||||
time = 2328000
|
||||
flags = 1
|
||||
data = length 288, hash 1C28C8BE
|
||||
sample 98:
|
||||
time = 2352000
|
||||
flags = 1
|
||||
data = length 336, hash C73E5D30
|
||||
sample 99:
|
||||
time = 2376000
|
||||
flags = 1
|
||||
data = length 288, hash 98B5BFF6
|
||||
sample 100:
|
||||
time = 2400000
|
||||
flags = 1
|
||||
data = length 336, hash E0135533
|
||||
sample 101:
|
||||
time = 2424000
|
||||
flags = 1
|
||||
data = length 336, hash D13C9DBC
|
||||
sample 102:
|
||||
time = 2448000
|
||||
flags = 1
|
||||
data = length 336, hash 63D524CA
|
||||
sample 103:
|
||||
time = 2472000
|
||||
flags = 1
|
||||
data = length 288, hash A28514C3
|
||||
sample 104:
|
||||
time = 2496000
|
||||
flags = 1
|
||||
data = length 336, hash 72B647FF
|
||||
sample 105:
|
||||
time = 2520000
|
||||
flags = 1
|
||||
data = length 336, hash 8F740AB1
|
||||
sample 106:
|
||||
time = 2544000
|
||||
flags = 1
|
||||
data = length 336, hash 5E3C7E93
|
||||
sample 107:
|
||||
time = 2568000
|
||||
flags = 1
|
||||
data = length 336, hash 121B913B
|
||||
sample 108:
|
||||
time = 2592000
|
||||
flags = 1
|
||||
data = length 336, hash 578FCCF2
|
||||
sample 109:
|
||||
time = 2616000
|
||||
flags = 1
|
||||
data = length 336, hash 5B5823DE
|
||||
sample 110:
|
||||
time = 2640000
|
||||
flags = 1
|
||||
data = length 384, hash D8B83F78
|
||||
sample 111:
|
||||
time = 2664000
|
||||
flags = 1
|
||||
data = length 240, hash E649682F
|
||||
sample 112:
|
||||
time = 2688000
|
||||
flags = 1
|
||||
data = length 96, hash C559A6F4
|
||||
sample 113:
|
||||
time = 2712000
|
||||
flags = 1
|
||||
data = length 96, hash 792796BC
|
||||
sample 114:
|
||||
time = 2736000
|
||||
flags = 1
|
||||
data = length 120, hash 8172CD0E
|
||||
sample 115:
|
||||
time = 2760000
|
||||
flags = 1
|
||||
data = length 120, hash F562B52F
|
||||
sample 116:
|
||||
time = 2784000
|
||||
flags = 1
|
||||
data = length 96, hash FF8D5B98
|
||||
tracksEnded = true
|
||||
359
library/extractor/src/test/assets/mp3/bear-vbr.mp3.1.dump
Normal file
359
library/extractor/src/test/assets/mp3/bear-vbr.mp3.1.dump
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2808000
|
||||
getPosition(0) = [[timeUs=0, position=237]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
format:
|
||||
bitrate = -1
|
||||
id = null
|
||||
containerMimeType = null
|
||||
sampleMimeType = audio/mpeg
|
||||
maxInputSize = 4096
|
||||
width = -1
|
||||
height = -1
|
||||
frameRate = -1.0
|
||||
rotationDegrees = 0
|
||||
pixelWidthHeightRatio = 1.0
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
pcmEncoding = -1
|
||||
encoderDelay = 576
|
||||
encoderPadding = 576
|
||||
subsampleOffsetUs = 9223372036854775807
|
||||
selectionFlags = 0
|
||||
language = null
|
||||
drmInitData = -
|
||||
metadata = entries=[TSSE: description=null: value=Lavf58.29.100]
|
||||
initializationData:
|
||||
total output bytes = 25920
|
||||
sample count = 82
|
||||
sample 0:
|
||||
time = 840000
|
||||
flags = 1
|
||||
data = length 288, hash 3E34B8D4
|
||||
sample 1:
|
||||
time = 864000
|
||||
flags = 1
|
||||
data = length 288, hash 9B96F72A
|
||||
sample 2:
|
||||
time = 888000
|
||||
flags = 1
|
||||
data = length 336, hash E917C122
|
||||
sample 3:
|
||||
time = 912000
|
||||
flags = 1
|
||||
data = length 336, hash 10ED1470
|
||||
sample 4:
|
||||
time = 936000
|
||||
flags = 1
|
||||
data = length 288, hash 706B8A7C
|
||||
sample 5:
|
||||
time = 960000
|
||||
flags = 1
|
||||
data = length 336, hash 71FFE4A0
|
||||
sample 6:
|
||||
time = 984000
|
||||
flags = 1
|
||||
data = length 336, hash D4160463
|
||||
sample 7:
|
||||
time = 1008000
|
||||
flags = 1
|
||||
data = length 336, hash EC557B14
|
||||
sample 8:
|
||||
time = 1032000
|
||||
flags = 1
|
||||
data = length 288, hash 5598CF8B
|
||||
sample 9:
|
||||
time = 1056000
|
||||
flags = 1
|
||||
data = length 336, hash 7E0AB41
|
||||
sample 10:
|
||||
time = 1080000
|
||||
flags = 1
|
||||
data = length 336, hash 1C585FEF
|
||||
sample 11:
|
||||
time = 1104000
|
||||
flags = 1
|
||||
data = length 336, hash A4A4855E
|
||||
sample 12:
|
||||
time = 1128000
|
||||
flags = 1
|
||||
data = length 336, hash CECA51D3
|
||||
sample 13:
|
||||
time = 1152000
|
||||
flags = 1
|
||||
data = length 288, hash 2D362DC5
|
||||
sample 14:
|
||||
time = 1176000
|
||||
flags = 1
|
||||
data = length 336, hash 9EB2609D
|
||||
sample 15:
|
||||
time = 1200000
|
||||
flags = 1
|
||||
data = length 336, hash 28FFB3FE
|
||||
sample 16:
|
||||
time = 1224000
|
||||
flags = 1
|
||||
data = length 288, hash 2AA2D216
|
||||
sample 17:
|
||||
time = 1248000
|
||||
flags = 1
|
||||
data = length 336, hash CDBC7032
|
||||
sample 18:
|
||||
time = 1272000
|
||||
flags = 1
|
||||
data = length 336, hash 25B13FE7
|
||||
sample 19:
|
||||
time = 1296000
|
||||
flags = 1
|
||||
data = length 336, hash DB6BB1E
|
||||
sample 20:
|
||||
time = 1320000
|
||||
flags = 1
|
||||
data = length 336, hash EBE951F4
|
||||
sample 21:
|
||||
time = 1344000
|
||||
flags = 1
|
||||
data = length 288, hash 9E2EBFF7
|
||||
sample 22:
|
||||
time = 1368000
|
||||
flags = 1
|
||||
data = length 336, hash 36A7D455
|
||||
sample 23:
|
||||
time = 1392000
|
||||
flags = 1
|
||||
data = length 336, hash 84545F8C
|
||||
sample 24:
|
||||
time = 1416000
|
||||
flags = 1
|
||||
data = length 336, hash F66F3045
|
||||
sample 25:
|
||||
time = 1440000
|
||||
flags = 1
|
||||
data = length 576, hash 5AB089EA
|
||||
sample 26:
|
||||
time = 1464000
|
||||
flags = 1
|
||||
data = length 336, hash 8868086
|
||||
sample 27:
|
||||
time = 1488000
|
||||
flags = 1
|
||||
data = length 336, hash D5EB6D63
|
||||
sample 28:
|
||||
time = 1512000
|
||||
flags = 1
|
||||
data = length 288, hash 7A5374B7
|
||||
sample 29:
|
||||
time = 1536000
|
||||
flags = 1
|
||||
data = length 336, hash BEB27A75
|
||||
sample 30:
|
||||
time = 1560000
|
||||
flags = 1
|
||||
data = length 336, hash E251E0FD
|
||||
sample 31:
|
||||
time = 1584000
|
||||
flags = 1
|
||||
data = length 288, hash D54C970
|
||||
sample 32:
|
||||
time = 1608000
|
||||
flags = 1
|
||||
data = length 336, hash 52C473B9
|
||||
sample 33:
|
||||
time = 1632000
|
||||
flags = 1
|
||||
data = length 336, hash F5F13334
|
||||
sample 34:
|
||||
time = 1656000
|
||||
flags = 1
|
||||
data = length 480, hash A5F1E987
|
||||
sample 35:
|
||||
time = 1680000
|
||||
flags = 1
|
||||
data = length 288, hash 453A1267
|
||||
sample 36:
|
||||
time = 1704000
|
||||
flags = 1
|
||||
data = length 288, hash 7C6C2EA9
|
||||
sample 37:
|
||||
time = 1728000
|
||||
flags = 1
|
||||
data = length 336, hash F4BFECA4
|
||||
sample 38:
|
||||
time = 1752000
|
||||
flags = 1
|
||||
data = length 336, hash 751A395A
|
||||
sample 39:
|
||||
time = 1776000
|
||||
flags = 1
|
||||
data = length 336, hash EE38DB02
|
||||
sample 40:
|
||||
time = 1800000
|
||||
flags = 1
|
||||
data = length 336, hash F18837E2
|
||||
sample 41:
|
||||
time = 1824000
|
||||
flags = 1
|
||||
data = length 336, hash ED36B78E
|
||||
sample 42:
|
||||
time = 1848000
|
||||
flags = 1
|
||||
data = length 336, hash B3D28289
|
||||
sample 43:
|
||||
time = 1872000
|
||||
flags = 1
|
||||
data = length 288, hash 8BDE28E1
|
||||
sample 44:
|
||||
time = 1896000
|
||||
flags = 1
|
||||
data = length 336, hash CFD5E966
|
||||
sample 45:
|
||||
time = 1920000
|
||||
flags = 1
|
||||
data = length 288, hash DC08E267
|
||||
sample 46:
|
||||
time = 1944000
|
||||
flags = 1
|
||||
data = length 336, hash 6530CB78
|
||||
sample 47:
|
||||
time = 1968000
|
||||
flags = 1
|
||||
data = length 336, hash 6CC6636E
|
||||
sample 48:
|
||||
time = 1992000
|
||||
flags = 1
|
||||
data = length 336, hash 613047C1
|
||||
sample 49:
|
||||
time = 2016000
|
||||
flags = 1
|
||||
data = length 288, hash CDC747BF
|
||||
sample 50:
|
||||
time = 2040000
|
||||
flags = 1
|
||||
data = length 336, hash AF22AA74
|
||||
sample 51:
|
||||
time = 2064000
|
||||
flags = 1
|
||||
data = length 384, hash 82F326AA
|
||||
sample 52:
|
||||
time = 2088000
|
||||
flags = 1
|
||||
data = length 384, hash EDA26C4D
|
||||
sample 53:
|
||||
time = 2112000
|
||||
flags = 1
|
||||
data = length 336, hash 94C643DC
|
||||
sample 54:
|
||||
time = 2136000
|
||||
flags = 1
|
||||
data = length 288, hash CB5D9C40
|
||||
sample 55:
|
||||
time = 2160000
|
||||
flags = 1
|
||||
data = length 336, hash 1E69DE3F
|
||||
sample 56:
|
||||
time = 2184000
|
||||
flags = 1
|
||||
data = length 336, hash 7E472219
|
||||
sample 57:
|
||||
time = 2208000
|
||||
flags = 1
|
||||
data = length 336, hash DA47B9FA
|
||||
sample 58:
|
||||
time = 2232000
|
||||
flags = 1
|
||||
data = length 336, hash DD0ABB7C
|
||||
sample 59:
|
||||
time = 2256000
|
||||
flags = 1
|
||||
data = length 288, hash DBF93FAC
|
||||
sample 60:
|
||||
time = 2280000
|
||||
flags = 1
|
||||
data = length 336, hash 243F4B2
|
||||
sample 61:
|
||||
time = 2304000
|
||||
flags = 1
|
||||
data = length 336, hash 2E881490
|
||||
sample 62:
|
||||
time = 2328000
|
||||
flags = 1
|
||||
data = length 288, hash 1C28C8BE
|
||||
sample 63:
|
||||
time = 2352000
|
||||
flags = 1
|
||||
data = length 336, hash C73E5D30
|
||||
sample 64:
|
||||
time = 2376000
|
||||
flags = 1
|
||||
data = length 288, hash 98B5BFF6
|
||||
sample 65:
|
||||
time = 2400000
|
||||
flags = 1
|
||||
data = length 336, hash E0135533
|
||||
sample 66:
|
||||
time = 2424000
|
||||
flags = 1
|
||||
data = length 336, hash D13C9DBC
|
||||
sample 67:
|
||||
time = 2448000
|
||||
flags = 1
|
||||
data = length 336, hash 63D524CA
|
||||
sample 68:
|
||||
time = 2472000
|
||||
flags = 1
|
||||
data = length 288, hash A28514C3
|
||||
sample 69:
|
||||
time = 2496000
|
||||
flags = 1
|
||||
data = length 336, hash 72B647FF
|
||||
sample 70:
|
||||
time = 2520000
|
||||
flags = 1
|
||||
data = length 336, hash 8F740AB1
|
||||
sample 71:
|
||||
time = 2544000
|
||||
flags = 1
|
||||
data = length 336, hash 5E3C7E93
|
||||
sample 72:
|
||||
time = 2568000
|
||||
flags = 1
|
||||
data = length 336, hash 121B913B
|
||||
sample 73:
|
||||
time = 2592000
|
||||
flags = 1
|
||||
data = length 336, hash 578FCCF2
|
||||
sample 74:
|
||||
time = 2616000
|
||||
flags = 1
|
||||
data = length 336, hash 5B5823DE
|
||||
sample 75:
|
||||
time = 2640000
|
||||
flags = 1
|
||||
data = length 384, hash D8B83F78
|
||||
sample 76:
|
||||
time = 2664000
|
||||
flags = 1
|
||||
data = length 240, hash E649682F
|
||||
sample 77:
|
||||
time = 2688000
|
||||
flags = 1
|
||||
data = length 96, hash C559A6F4
|
||||
sample 78:
|
||||
time = 2712000
|
||||
flags = 1
|
||||
data = length 96, hash 792796BC
|
||||
sample 79:
|
||||
time = 2736000
|
||||
flags = 1
|
||||
data = length 120, hash 8172CD0E
|
||||
sample 80:
|
||||
time = 2760000
|
||||
flags = 1
|
||||
data = length 120, hash F562B52F
|
||||
sample 81:
|
||||
time = 2784000
|
||||
flags = 1
|
||||
data = length 96, hash FF8D5B98
|
||||
tracksEnded = true
|
||||
199
library/extractor/src/test/assets/mp3/bear-vbr.mp3.2.dump
Normal file
199
library/extractor/src/test/assets/mp3/bear-vbr.mp3.2.dump
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2808000
|
||||
getPosition(0) = [[timeUs=0, position=237]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
format:
|
||||
bitrate = -1
|
||||
id = null
|
||||
containerMimeType = null
|
||||
sampleMimeType = audio/mpeg
|
||||
maxInputSize = 4096
|
||||
width = -1
|
||||
height = -1
|
||||
frameRate = -1.0
|
||||
rotationDegrees = 0
|
||||
pixelWidthHeightRatio = 1.0
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
pcmEncoding = -1
|
||||
encoderDelay = 576
|
||||
encoderPadding = 576
|
||||
subsampleOffsetUs = 9223372036854775807
|
||||
selectionFlags = 0
|
||||
language = null
|
||||
drmInitData = -
|
||||
metadata = entries=[TSSE: description=null: value=Lavf58.29.100]
|
||||
initializationData:
|
||||
total output bytes = 12624
|
||||
sample count = 42
|
||||
sample 0:
|
||||
time = 1800000
|
||||
flags = 1
|
||||
data = length 336, hash F18837E2
|
||||
sample 1:
|
||||
time = 1824000
|
||||
flags = 1
|
||||
data = length 336, hash ED36B78E
|
||||
sample 2:
|
||||
time = 1848000
|
||||
flags = 1
|
||||
data = length 336, hash B3D28289
|
||||
sample 3:
|
||||
time = 1872000
|
||||
flags = 1
|
||||
data = length 288, hash 8BDE28E1
|
||||
sample 4:
|
||||
time = 1896000
|
||||
flags = 1
|
||||
data = length 336, hash CFD5E966
|
||||
sample 5:
|
||||
time = 1920000
|
||||
flags = 1
|
||||
data = length 288, hash DC08E267
|
||||
sample 6:
|
||||
time = 1944000
|
||||
flags = 1
|
||||
data = length 336, hash 6530CB78
|
||||
sample 7:
|
||||
time = 1968000
|
||||
flags = 1
|
||||
data = length 336, hash 6CC6636E
|
||||
sample 8:
|
||||
time = 1992000
|
||||
flags = 1
|
||||
data = length 336, hash 613047C1
|
||||
sample 9:
|
||||
time = 2016000
|
||||
flags = 1
|
||||
data = length 288, hash CDC747BF
|
||||
sample 10:
|
||||
time = 2040000
|
||||
flags = 1
|
||||
data = length 336, hash AF22AA74
|
||||
sample 11:
|
||||
time = 2064000
|
||||
flags = 1
|
||||
data = length 384, hash 82F326AA
|
||||
sample 12:
|
||||
time = 2088000
|
||||
flags = 1
|
||||
data = length 384, hash EDA26C4D
|
||||
sample 13:
|
||||
time = 2112000
|
||||
flags = 1
|
||||
data = length 336, hash 94C643DC
|
||||
sample 14:
|
||||
time = 2136000
|
||||
flags = 1
|
||||
data = length 288, hash CB5D9C40
|
||||
sample 15:
|
||||
time = 2160000
|
||||
flags = 1
|
||||
data = length 336, hash 1E69DE3F
|
||||
sample 16:
|
||||
time = 2184000
|
||||
flags = 1
|
||||
data = length 336, hash 7E472219
|
||||
sample 17:
|
||||
time = 2208000
|
||||
flags = 1
|
||||
data = length 336, hash DA47B9FA
|
||||
sample 18:
|
||||
time = 2232000
|
||||
flags = 1
|
||||
data = length 336, hash DD0ABB7C
|
||||
sample 19:
|
||||
time = 2256000
|
||||
flags = 1
|
||||
data = length 288, hash DBF93FAC
|
||||
sample 20:
|
||||
time = 2280000
|
||||
flags = 1
|
||||
data = length 336, hash 243F4B2
|
||||
sample 21:
|
||||
time = 2304000
|
||||
flags = 1
|
||||
data = length 336, hash 2E881490
|
||||
sample 22:
|
||||
time = 2328000
|
||||
flags = 1
|
||||
data = length 288, hash 1C28C8BE
|
||||
sample 23:
|
||||
time = 2352000
|
||||
flags = 1
|
||||
data = length 336, hash C73E5D30
|
||||
sample 24:
|
||||
time = 2376000
|
||||
flags = 1
|
||||
data = length 288, hash 98B5BFF6
|
||||
sample 25:
|
||||
time = 2400000
|
||||
flags = 1
|
||||
data = length 336, hash E0135533
|
||||
sample 26:
|
||||
time = 2424000
|
||||
flags = 1
|
||||
data = length 336, hash D13C9DBC
|
||||
sample 27:
|
||||
time = 2448000
|
||||
flags = 1
|
||||
data = length 336, hash 63D524CA
|
||||
sample 28:
|
||||
time = 2472000
|
||||
flags = 1
|
||||
data = length 288, hash A28514C3
|
||||
sample 29:
|
||||
time = 2496000
|
||||
flags = 1
|
||||
data = length 336, hash 72B647FF
|
||||
sample 30:
|
||||
time = 2520000
|
||||
flags = 1
|
||||
data = length 336, hash 8F740AB1
|
||||
sample 31:
|
||||
time = 2544000
|
||||
flags = 1
|
||||
data = length 336, hash 5E3C7E93
|
||||
sample 32:
|
||||
time = 2568000
|
||||
flags = 1
|
||||
data = length 336, hash 121B913B
|
||||
sample 33:
|
||||
time = 2592000
|
||||
flags = 1
|
||||
data = length 336, hash 578FCCF2
|
||||
sample 34:
|
||||
time = 2616000
|
||||
flags = 1
|
||||
data = length 336, hash 5B5823DE
|
||||
sample 35:
|
||||
time = 2640000
|
||||
flags = 1
|
||||
data = length 384, hash D8B83F78
|
||||
sample 36:
|
||||
time = 2664000
|
||||
flags = 1
|
||||
data = length 240, hash E649682F
|
||||
sample 37:
|
||||
time = 2688000
|
||||
flags = 1
|
||||
data = length 96, hash C559A6F4
|
||||
sample 38:
|
||||
time = 2712000
|
||||
flags = 1
|
||||
data = length 96, hash 792796BC
|
||||
sample 39:
|
||||
time = 2736000
|
||||
flags = 1
|
||||
data = length 120, hash 8172CD0E
|
||||
sample 40:
|
||||
time = 2760000
|
||||
flags = 1
|
||||
data = length 120, hash F562B52F
|
||||
sample 41:
|
||||
time = 2784000
|
||||
flags = 1
|
||||
data = length 96, hash FF8D5B98
|
||||
tracksEnded = true
|
||||
39
library/extractor/src/test/assets/mp3/bear-vbr.mp3.3.dump
Normal file
39
library/extractor/src/test/assets/mp3/bear-vbr.mp3.3.dump
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2808000
|
||||
getPosition(0) = [[timeUs=0, position=237]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
format:
|
||||
bitrate = -1
|
||||
id = null
|
||||
containerMimeType = null
|
||||
sampleMimeType = audio/mpeg
|
||||
maxInputSize = 4096
|
||||
width = -1
|
||||
height = -1
|
||||
frameRate = -1.0
|
||||
rotationDegrees = 0
|
||||
pixelWidthHeightRatio = 1.0
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
pcmEncoding = -1
|
||||
encoderDelay = 576
|
||||
encoderPadding = 576
|
||||
subsampleOffsetUs = 9223372036854775807
|
||||
selectionFlags = 0
|
||||
language = null
|
||||
drmInitData = -
|
||||
metadata = entries=[TSSE: description=null: value=Lavf58.29.100]
|
||||
initializationData:
|
||||
total output bytes = 216
|
||||
sample count = 2
|
||||
sample 0:
|
||||
time = 2760000
|
||||
flags = 1
|
||||
data = length 120, hash F562B52F
|
||||
sample 1:
|
||||
time = 2784000
|
||||
flags = 1
|
||||
data = length 96, hash FF8D5B98
|
||||
tracksEnded = true
|
||||
|
|
@ -35,6 +35,12 @@ public final class Mp3ExtractorTest {
|
|||
Mp3Extractor::new, "mp3/bear-cbr-variable-frame-size-no-seek-table.mp3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMp3SampleWithIndexSeeker() throws Exception {
|
||||
ExtractorAsserts.assertBehavior(
|
||||
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING), "mp3/bear-vbr.mp3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrimmedMp3Sample() throws Exception {
|
||||
ExtractorAsserts.assertBehavior(Mp3Extractor::new, "mp3/play-trimmed.mp3");
|
||||
|
|
|
|||
Loading…
Reference in a new issue