Implement binary search seeking for FLAC extractor

PiperOrigin-RevId: 284814594
This commit is contained in:
kimvde 2019-12-10 19:40:26 +00:00 committed by Oliver Woodman
parent 65adcdaeb9
commit a95c28a929
54 changed files with 3967 additions and 166 deletions

View File

@ -4,8 +4,7 @@
* Add Java FLAC extractor
([#6406](https://github.com/google/ExoPlayer/issues/6406)).
This extractor does not support seeking and live streams. If
`DefaultExtractorsFactory` is used, this extractor is only used if the FLAC
If `DefaultExtractorsFactory` is used, this extractor is only used if the FLAC
extension is not loaded.
* Make `MediaSourceEventListener.LoadEventInfo` and
`MediaSourceEventListener.MediaLoadData` top-level classes.

View File

@ -19,6 +19,7 @@ import com.google.android.exoplayer2.extractor.BinarySearchSeeker;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.FlacConstants;
import com.google.android.exoplayer2.util.FlacStreamMetadata;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -49,6 +50,15 @@ import java.nio.ByteBuffer;
private final FlacDecoderJni decoderJni;
/**
* Creates a {@link FlacBinarySearchSeeker}.
*
* @param streamMetadata The stream metadata.
* @param firstFramePosition The byte offset of the first frame in the stream.
* @param inputLength The length of the stream in bytes.
* @param decoderJni The FLAC JNI decoder.
* @param outputFrameHolder A holder used to retrieve the frame found by a seeking operation.
*/
public FlacBinarySearchSeeker(
FlacStreamMetadata streamMetadata,
long firstFramePosition,
@ -56,7 +66,7 @@ import java.nio.ByteBuffer;
FlacDecoderJni decoderJni,
OutputFrameHolder outputFrameHolder) {
super(
new FlacSeekTimestampConverter(streamMetadata),
/* seekTimestampConverter= */ streamMetadata::getSampleNumber,
new FlacTimestampSeeker(decoderJni, outputFrameHolder),
streamMetadata.getDurationUs(),
/* floorTimePosition= */ 0,
@ -64,7 +74,8 @@ import java.nio.ByteBuffer;
/* floorBytePosition= */ firstFramePosition,
/* ceilingBytePosition= */ inputLength,
/* approxBytesPerFrame= */ streamMetadata.getApproxBytesPerFrame(),
/* minimumSearchRange= */ Math.max(1, streamMetadata.minFrameSize));
/* minimumSearchRange= */ Math.max(
FlacConstants.MIN_FRAME_HEADER_SIZE, streamMetadata.minFrameSize));
this.decoderJni = Assertions.checkNotNull(decoderJni);
}
@ -124,21 +135,4 @@ import java.nio.ByteBuffer;
}
}
}
/**
* A {@link SeekTimestampConverter} implementation that returns the frame index (sample index) as
* the timestamp for a stream seek time position.
*/
private static final class FlacSeekTimestampConverter implements SeekTimestampConverter {
private final FlacStreamMetadata streamMetadata;
public FlacSeekTimestampConverter(FlacStreamMetadata streamMetadata) {
this.streamMetadata = streamMetadata;
}
@Override
public long timeUsToTargetTime(long timeUs) {
return Assertions.checkNotNull(streamMetadata).getSampleIndex(timeUs);
}
}
}

View File

@ -239,7 +239,10 @@ public final class DefaultExtractorsFactory implements ExtractorsFactory {
? AmrExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
: 0));
extractors[12] = new Ac4Extractor();
// Prefer the FLAC extension extractor because it supports seeking.
// Prefer the FLAC extension extractor because it outputs raw audio, which can be handled by the
// framework on all API levels, unlike the core library FLAC extractor, which outputs FLAC audio
// frames and so relies on having a FLAC decoder (e.g., a MediaCodec decoder that handles FLAC
// (from API 27), or the FFmpeg extension with FLAC enabled).
if (FLAC_EXTENSION_EXTRACTOR_CONSTRUCTOR != null) {
try {
extractors[13] = FLAC_EXTENSION_EXTRACTOR_CONSTRUCTOR.newInstance();

View File

@ -15,22 +15,25 @@
*/
package com.google.android.exoplayer2.extractor;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.FlacConstants;
import com.google.android.exoplayer2.util.FlacStreamMetadata;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
/** Reads and peeks FLAC frame elements. */
public final class FlacFrameReader {
/** Holds a frame block size. */
public static final class BlockSizeHolder {
/** The block size in samples. */
public int blockSizeSamples;
/** Holds a sample number. */
public static final class SampleNumberHolder {
/** The sample number. */
public long sampleNumber;
}
/**
* Checks whether the given FLAC frame header is valid and, if so, reads it and writes the frame
* block size in {@code blockSizeHolder}.
* first sample number in {@code sampleNumberHolder}.
*
* <p>If the header is valid, the position of {@code scratch} is moved to the byte following it.
* Otherwise, there is no guarantee on the position.
@ -39,14 +42,14 @@ public final class FlacFrameReader {
* header.
* @param flacStreamMetadata The stream metadata.
* @param frameStartMarker The frame start marker of the stream.
* @param blockSizeHolder The holder used to contain the block size.
* @param sampleNumberHolder The holder used to contain the sample number.
* @return Whether the frame header is valid.
*/
public static boolean checkAndReadFrameHeader(
ParsableByteArray scratch,
FlacStreamMetadata flacStreamMetadata,
int frameStartMarker,
BlockSizeHolder blockSizeHolder) {
SampleNumberHolder sampleNumberHolder) {
int frameStartPosition = scratch.getPosition();
long frameHeaderBytes = scratch.readUnsignedInt();
@ -54,6 +57,7 @@ public final class FlacFrameReader {
return false;
}
boolean isBlockSizeVariable = (frameHeaderBytes >>> 16 & 1) == 1;
int blockSizeKey = (int) (frameHeaderBytes >> 12 & 0xF);
int sampleRateKey = (int) (frameHeaderBytes >> 8 & 0xF);
int channelAssignmentKey = (int) (frameHeaderBytes >> 4 & 0xF);
@ -62,32 +66,67 @@ public final class FlacFrameReader {
return checkChannelAssignment(channelAssignmentKey, flacStreamMetadata)
&& checkBitsPerSample(bitsPerSampleKey, flacStreamMetadata)
&& !reservedBit
&& checkAndReadUtf8Data(scratch)
&& checkAndReadBlockSizeSamples(scratch, flacStreamMetadata, blockSizeKey, blockSizeHolder)
&& checkAndReadFirstSampleNumber(
scratch, flacStreamMetadata, isBlockSizeVariable, sampleNumberHolder)
&& checkAndReadBlockSizeSamples(scratch, flacStreamMetadata, blockSizeKey)
&& checkAndReadSampleRate(scratch, flacStreamMetadata, sampleRateKey)
&& checkAndReadCrc(scratch, frameStartPosition);
}
/**
* Returns the block size of the given frame.
* Checks whether the given FLAC frame header is valid and, if so, writes the frame first sample
* number in {@code sampleNumberHolder}.
*
* <p>If no exception is thrown, the position of {@code scratch} is left unchanged. Otherwise,
* there is no guarantee on the position.
* <p>The {@code input} peek position is left unchanged.
*
* @param scratch The array to get the data from, whose position must correspond to the start of a
* frame.
* @return The block size in samples, or -1 if the block size is invalid.
* @param input The input to get the data from, whose peek position must correspond to the frame
* header.
* @param flacStreamMetadata The stream metadata.
* @param frameStartMarker The frame start marker of the stream.
* @param sampleNumberHolder The holder used to contain the sample number.
* @return Whether the frame header is valid.
*/
public static int getFrameBlockSizeSamples(ParsableByteArray scratch) {
int blockSizeKey = (scratch.data[2] & 0xFF) >> 4;
if (blockSizeKey < 6 || blockSizeKey > 7) {
return readFrameBlockSizeSamplesFromKey(scratch, blockSizeKey);
public static boolean checkFrameHeaderFromPeek(
ExtractorInput input,
FlacStreamMetadata flacStreamMetadata,
int frameStartMarker,
SampleNumberHolder sampleNumberHolder)
throws IOException, InterruptedException {
long originalPeekPosition = input.getPeekPosition();
byte[] frameStartBytes = new byte[2];
input.peekFully(frameStartBytes, 0, 2);
int frameStart = (frameStartBytes[0] & 0xFF) << 8 | (frameStartBytes[1] & 0xFF);
if (frameStart != frameStartMarker) {
input.resetPeekPosition();
input.advancePeekPosition((int) (originalPeekPosition - input.getPosition()));
return false;
}
scratch.skipBytes(4);
scratch.readUtf8EncodedLong();
int blockSizeSamples = readFrameBlockSizeSamplesFromKey(scratch, blockSizeKey);
scratch.setPosition(0);
return blockSizeSamples;
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
System.arraycopy(
frameStartBytes, /* srcPos= */ 0, scratch.data, /* destPos= */ 0, /* length= */ 2);
int totalBytesPeeked = 2;
while (totalBytesPeeked < FlacConstants.MAX_FRAME_HEADER_SIZE) {
int bytesPeeked =
input.peek(
scratch.data,
totalBytesPeeked,
FlacConstants.MAX_FRAME_HEADER_SIZE - totalBytesPeeked);
if (bytesPeeked == C.RESULT_END_OF_INPUT) {
// The size of the last frame is less than MAX_FRAME_HEADER_SIZE.
break;
}
totalBytesPeeked += bytesPeeked;
}
scratch.setLimit(totalBytesPeeked);
input.resetPeekPosition();
input.advancePeekPosition((int) (originalPeekPosition - input.getPosition()));
return checkAndReadFrameHeader(
scratch, flacStreamMetadata, frameStartMarker, sampleNumberHolder);
}
/**
@ -159,27 +198,40 @@ public final class FlacFrameReader {
}
/**
* Checks whether the given UTF-8 data is valid and, if so, reads it.
* Checks whether the given sample number is valid and, if so, reads it and writes it in {@code
* sampleNumberHolder}.
*
* <p>If the UTF-8 data is valid, the position of {@code scratch} is moved to the byte following
* it. Otherwise, there is no guarantee on the position.
* <p>If the sample number is valid, the position of {@code scratch} is moved to the byte
* following it. Otherwise, there is no guarantee on the position.
*
* @param scratch The array to read the data from, whose position must correspond to the UTF-8
* data.
* @return Whether the UTF-8 data is valid.
* @param scratch The array to read the data from, whose position must correspond to the sample
* number data.
* @param flacStreamMetadata The stream metadata.
* @param isBlockSizeVariable Whether the stream blocking strategy is variable block size or fixed
* block size.
* @param sampleNumberHolder The holder used to contain the sample number.
* @return Whether the sample number is valid.
*/
private static boolean checkAndReadUtf8Data(ParsableByteArray scratch) {
private static boolean checkAndReadFirstSampleNumber(
ParsableByteArray scratch,
FlacStreamMetadata flacStreamMetadata,
boolean isBlockSizeVariable,
SampleNumberHolder sampleNumberHolder) {
long utf8Value;
try {
scratch.readUtf8EncodedLong();
utf8Value = scratch.readUtf8EncodedLong();
} catch (NumberFormatException e) {
return false;
}
sampleNumberHolder.sampleNumber =
isBlockSizeVariable ? utf8Value : utf8Value * flacStreamMetadata.maxBlockSizeSamples;
return true;
}
/**
* Checks whether the given frame block size key and block size bits are valid and, if so, reads
* the block size bits and writes the block size in {@code blockSizeHolder}.
* the block size bits.
*
* <p>If the block size is valid, the position of {@code scratch} is moved to the byte following
* the block size bits. Otherwise, there is no guarantee on the position.
@ -188,20 +240,12 @@ public final class FlacFrameReader {
* size bits.
* @param flacStreamMetadata The stream metadata.
* @param blockSizeKey The key in the block size lookup table.
* @param blockSizeHolder The holder used to contain the block size.
* @return Whether the block size is valid.
*/
private static boolean checkAndReadBlockSizeSamples(
ParsableByteArray scratch,
FlacStreamMetadata flacStreamMetadata,
int blockSizeKey,
BlockSizeHolder blockSizeHolder) {
ParsableByteArray scratch, FlacStreamMetadata flacStreamMetadata, int blockSizeKey) {
int blockSizeSamples = readFrameBlockSizeSamplesFromKey(scratch, blockSizeKey);
if (blockSizeSamples == -1 || blockSizeSamples > flacStreamMetadata.maxBlockSizeSamples) {
return false;
}
blockSizeHolder.blockSizeSamples = blockSizeSamples;
return true;
return blockSizeSamples != -1 && blockSizeSamples <= flacStreamMetadata.maxBlockSizeSamples;
}
/**

View File

@ -45,19 +45,6 @@ public final class FlacMetadataReader {
}
}
/** Holds the metadata extracted from the first frame. */
public static final class FirstFrameMetadata {
/** The frame start marker, which should correspond to the 2 first bytes of each frame. */
public final int frameStartMarker;
/** The block size in samples. */
public final int blockSizeSamples;
public FirstFrameMetadata(int frameStartMarker, int blockSizeSamples) {
this.frameStartMarker = frameStartMarker;
this.blockSizeSamples = blockSizeSamples;
}
}
private static final int STREAM_MARKER = 0x664C6143; // ASCII for "fLaC"
private static final int SYNC_CODE = 0x3FFE;
private static final int STREAM_INFO_TYPE = 0;
@ -204,23 +191,22 @@ public final class FlacMetadataReader {
}
/**
* Returns some metadata extracted from the first frame of a FLAC stream.
* Returns the frame start marker, consisting of the 2 first bytes of the first frame.
*
* <p>The read position of {@code input} is left unchanged and the peek position is aligned with
* the read position.
*
* @param input Input stream to get the metadata from (starting from the read position).
* @return A {@link FirstFrameMetadata} containing the frame start marker (which should be the
* same for all the frames in the stream) and the block size of the frame.
* @throws ParserException If an error occurs parsing the frame metadata.
* @param input Input stream to get the start marker from (starting from the read position).
* @return The frame start marker (which must be the same for all the frames in the stream).
* @throws ParserException If an error occurs parsing the frame start marker.
* @throws IOException If peeking from the input fails.
* @throws InterruptedException If interrupted while peeking from input.
*/
public static FirstFrameMetadata getFirstFrameMetadata(ExtractorInput input)
public static int getFrameStartMarker(ExtractorInput input)
throws IOException, InterruptedException {
input.resetPeekPosition();
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
input.peekFully(scratch.data, 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
ParsableByteArray scratch = new ParsableByteArray(2);
input.peekFully(scratch.data, 0, 2);
int frameStartMarker = scratch.readUnsignedShort();
int syncCode = frameStartMarker >> 2;
@ -229,11 +215,8 @@ public final class FlacMetadataReader {
throw new ParserException("First frame does not start with sync code.");
}
scratch.setPosition(0);
int firstFrameBlockSizeSamples = FlacFrameReader.getFrameBlockSizeSamples(scratch);
input.resetPeekPosition();
return new FirstFrameMetadata(frameStartMarker, firstFrameBlockSizeSamples);
return frameStartMarker;
}
private static FlacStreamMetadata readStreamInfoBlock(ExtractorInput input)

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2019 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.flac;
import com.google.android.exoplayer2.extractor.BinarySearchSeeker;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.FlacFrameReader;
import com.google.android.exoplayer2.extractor.FlacFrameReader.SampleNumberHolder;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.util.FlacConstants;
import com.google.android.exoplayer2.util.FlacStreamMetadata;
import java.io.IOException;
/**
* A {@link SeekMap} implementation for FLAC stream using binary search.
*
* <p>This seeker performs seeking by using binary search within the stream, until it finds the
* frame that contains the target sample.
*/
/* package */ final class FlacBinarySearchSeeker extends BinarySearchSeeker {
/**
* Creates a {@link FlacBinarySearchSeeker}.
*
* @param flacStreamMetadata The stream metadata.
* @param frameStartMarker The frame start marker, consisting of the 2 bytes by which every frame
* in the stream must start.
* @param firstFramePosition The byte offset of the first frame in the stream.
* @param inputLength The length of the stream in bytes.
* @param sampleNumberHolder A holder used to retrieve the sample number of a frame found by a
* seeking operation.
*/
public FlacBinarySearchSeeker(
FlacStreamMetadata flacStreamMetadata,
int frameStartMarker,
long firstFramePosition,
long inputLength,
SampleNumberHolder sampleNumberHolder) {
super(
/* seekTimestampConverter= */ flacStreamMetadata::getSampleNumber,
new FlacTimestampSeeker(flacStreamMetadata, frameStartMarker, sampleNumberHolder),
flacStreamMetadata.getDurationUs(),
/* floorTimePosition= */ 0,
/* ceilingTimePosition= */ flacStreamMetadata.totalSamples,
/* floorBytePosition= */ firstFramePosition,
/* ceilingBytePosition= */ inputLength,
/* approxBytesPerFrame= */ flacStreamMetadata.getApproxBytesPerFrame(),
/* minimumSearchRange= */ Math.max(
FlacConstants.MIN_FRAME_HEADER_SIZE, flacStreamMetadata.minFrameSize));
}
private static final class FlacTimestampSeeker implements TimestampSeeker {
private final FlacStreamMetadata flacStreamMetadata;
private final int frameStartMarker;
private final SampleNumberHolder foundFrameSampleNumberHolder;
private final SampleNumberHolder tempSampleNumberHolder;
private FlacTimestampSeeker(
FlacStreamMetadata flacStreamMetadata,
int frameStartMarker,
SampleNumberHolder foundFrameSampleNumberHolder) {
this.flacStreamMetadata = flacStreamMetadata;
this.frameStartMarker = frameStartMarker;
this.foundFrameSampleNumberHolder = foundFrameSampleNumberHolder;
tempSampleNumberHolder = new SampleNumberHolder();
}
@Override
public TimestampSearchResult searchForTimestamp(ExtractorInput input, long targetSampleIndex)
throws IOException, InterruptedException {
long searchPosition = input.getPosition();
// Find left frame.
long leftFrameFirstSampleNumber = findNextFrame(input);
long leftFramePosition = input.getPeekPosition();
input.advancePeekPosition(
Math.max(FlacConstants.MIN_FRAME_HEADER_SIZE, flacStreamMetadata.minFrameSize));
// Find right frame.
long rightFrameFirstSampleNumber = findNextFrame(input);
long rightFramePosition = input.getPeekPosition();
if (leftFrameFirstSampleNumber <= targetSampleIndex
&& rightFrameFirstSampleNumber > targetSampleIndex) {
foundFrameSampleNumberHolder.sampleNumber = leftFrameFirstSampleNumber;
return TimestampSearchResult.targetFoundResult(leftFramePosition);
} else if (rightFrameFirstSampleNumber <= targetSampleIndex) {
return TimestampSearchResult.underestimatedResult(
rightFrameFirstSampleNumber, rightFramePosition);
} else {
return TimestampSearchResult.overestimatedResult(
leftFrameFirstSampleNumber, searchPosition);
}
}
/**
* Searches for the next frame in {@code input}.
*
* <p>The peek position is advanced to the start of the found frame, or at the end of the stream
* if no frame was found.
*
* @param input The input from which to search (starting from the peek position).
* @return The number of the first sample in the found frame, or the total number of samples in
* the stream if no frame was found.
* @throws IOException If peeking from the input fails. In this case, there is no guarantee on
* the peek position.
* @throws InterruptedException If interrupted while peeking from input. In this case, there is
* no guarantee on the peek position.
*/
private long findNextFrame(ExtractorInput input) throws IOException, InterruptedException {
while (input.getPeekPosition() < input.getLength() - FlacConstants.MIN_FRAME_HEADER_SIZE
&& !FlacFrameReader.checkFrameHeaderFromPeek(
input, flacStreamMetadata, frameStartMarker, tempSampleNumberHolder)) {
input.advancePeekPosition(1);
}
if (input.getPeekPosition() >= input.getLength() - FlacConstants.MIN_FRAME_HEADER_SIZE) {
input.advancePeekPosition((int) (input.getLength() - input.getPeekPosition()));
return flacStreamMetadata.totalSamples;
}
return tempSampleNumberHolder.sampleNumber;
}
}
}

View File

@ -25,9 +25,8 @@ import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.extractor.FlacFrameReader;
import com.google.android.exoplayer2.extractor.FlacFrameReader.BlockSizeHolder;
import com.google.android.exoplayer2.extractor.FlacFrameReader.SampleNumberHolder;
import com.google.android.exoplayer2.extractor.FlacMetadataReader;
import com.google.android.exoplayer2.extractor.FlacMetadataReader.FirstFrameMetadata;
import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.TrackOutput;
@ -42,7 +41,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// TODO: implement seeking.
// TODO: implement seeking using the optional seek table.
/**
* Extracts data from FLAC container format.
*
@ -78,7 +77,7 @@ public final class FlacExtractor implements Extractor {
STATE_GET_STREAM_MARKER_AND_INFO_BLOCK_BYTES,
STATE_READ_STREAM_MARKER,
STATE_READ_METADATA_BLOCKS,
STATE_GET_FIRST_FRAME_METADATA,
STATE_GET_FRAME_START_MARKER,
STATE_READ_FRAMES
})
private @interface State {}
@ -87,20 +86,20 @@ public final class FlacExtractor implements Extractor {
private static final int STATE_GET_STREAM_MARKER_AND_INFO_BLOCK_BYTES = 1;
private static final int STATE_READ_STREAM_MARKER = 2;
private static final int STATE_READ_METADATA_BLOCKS = 3;
private static final int STATE_GET_FIRST_FRAME_METADATA = 4;
private static final int STATE_GET_FRAME_START_MARKER = 4;
private static final int STATE_READ_FRAMES = 5;
/** Arbitrary scratch length of 32KB, which is ~170ms of 16-bit stereo PCM audio at 48KHz. */
private static final int SCRATCH_LENGTH = 32 * 1024;
/** Value of an unknown block size. */
private static final int BLOCK_SIZE_UNKNOWN = -1;
/** Value of an unknown sample number. */
private static final int SAMPLE_NUMBER_UNKNOWN = -1;
private final byte[] streamMarkerAndInfoBlock;
private final ParsableByteArray scratch;
private final boolean id3MetadataDisabled;
private final BlockSizeHolder blockSizeHolder;
private final SampleNumberHolder sampleNumberHolder;
@MonotonicNonNull private ExtractorOutput extractorOutput;
@MonotonicNonNull private TrackOutput trackOutput;
@ -110,9 +109,9 @@ public final class FlacExtractor implements Extractor {
@MonotonicNonNull private FlacStreamMetadata flacStreamMetadata;
private int minFrameSize;
private int frameStartMarker;
private int currentFrameBlockSizeSamples;
@MonotonicNonNull private FlacBinarySearchSeeker binarySearchSeeker;
private int currentFrameBytesWritten;
private long totalSamplesWritten;
private long currentFrameFirstSampleNumber;
/** Constructs an instance with {@code flags = 0}. */
public FlacExtractor() {
@ -129,8 +128,8 @@ public final class FlacExtractor implements Extractor {
streamMarkerAndInfoBlock =
new byte[FlacConstants.STREAM_MARKER_SIZE + FlacConstants.STREAM_INFO_BLOCK_SIZE];
scratch = new ParsableByteArray(SCRATCH_LENGTH);
blockSizeHolder = new BlockSizeHolder();
id3MetadataDisabled = (flags & FLAG_DISABLE_ID3_METADATA) != 0;
sampleNumberHolder = new SampleNumberHolder();
}
@Override
@ -147,7 +146,7 @@ public final class FlacExtractor implements Extractor {
}
@Override
public int read(ExtractorInput input, PositionHolder seekPosition)
public @ReadResult int read(ExtractorInput input, PositionHolder seekPosition)
throws IOException, InterruptedException {
switch (state) {
case STATE_READ_ID3_METADATA:
@ -162,11 +161,11 @@ public final class FlacExtractor implements Extractor {
case STATE_READ_METADATA_BLOCKS:
readMetadataBlocks(input);
return Extractor.RESULT_CONTINUE;
case STATE_GET_FIRST_FRAME_METADATA:
getFirstFrameMetadata(input);
case STATE_GET_FRAME_START_MARKER:
getFrameStartMarker(input);
return Extractor.RESULT_CONTINUE;
case STATE_READ_FRAMES:
return readFrames(input);
return readFrames(input, seekPosition);
default:
throw new IllegalStateException();
}
@ -174,9 +173,13 @@ public final class FlacExtractor implements Extractor {
@Override
public void seek(long position, long timeUs) {
state = STATE_READ_ID3_METADATA;
if (position == 0) {
state = STATE_READ_ID3_METADATA;
currentFrameFirstSampleNumber = 0;
} else if (binarySearchSeeker != null) {
binarySearchSeeker.setSeekTargetUs(timeUs);
}
currentFrameBytesWritten = 0;
totalSamplesWritten = 0;
scratch.reset();
}
@ -218,25 +221,33 @@ public final class FlacExtractor implements Extractor {
minFrameSize = Math.max(flacStreamMetadata.minFrameSize, FlacConstants.MIN_FRAME_HEADER_SIZE);
castNonNull(trackOutput)
.format(flacStreamMetadata.getFormat(streamMarkerAndInfoBlock, id3Metadata));
castNonNull(extractorOutput)
.seekMap(new SeekMap.Unseekable(flacStreamMetadata.getDurationUs()));
state = STATE_GET_FIRST_FRAME_METADATA;
state = STATE_GET_FRAME_START_MARKER;
}
private void getFirstFrameMetadata(ExtractorInput input)
throws IOException, InterruptedException {
FirstFrameMetadata firstFrameMetadata = FlacMetadataReader.getFirstFrameMetadata(input);
frameStartMarker = firstFrameMetadata.frameStartMarker;
currentFrameBlockSizeSamples = firstFrameMetadata.blockSizeSamples;
private void getFrameStartMarker(ExtractorInput input) throws IOException, InterruptedException {
frameStartMarker = FlacMetadataReader.getFrameStartMarker(input);
castNonNull(extractorOutput)
.seekMap(
getSeekMap(
/* firstFramePosition= */ (int) input.getPosition(),
/* streamLength= */ input.getLength()));
state = STATE_READ_FRAMES;
}
private int readFrames(ExtractorInput input) throws IOException, InterruptedException {
private @ReadResult int readFrames(ExtractorInput input, PositionHolder seekPosition)
throws IOException, InterruptedException {
Assertions.checkNotNull(trackOutput);
Assertions.checkNotNull(flacStreamMetadata);
// Handle pending seek if necessary.
if (binarySearchSeeker != null && binarySearchSeeker.isSeeking()) {
int seekResult = binarySearchSeeker.handlePendingSeek(input, seekPosition);
currentFrameFirstSampleNumber = sampleNumberHolder.sampleNumber;
return seekResult;
}
// Copy more bytes into the scratch.
int currentLimit = scratch.limit();
int bytesRead =
@ -246,7 +257,8 @@ public final class FlacExtractor implements Extractor {
if (!foundEndOfInput) {
scratch.setLimit(currentLimit + bytesRead);
} else if (scratch.bytesLeft() == 0) {
return C.RESULT_END_OF_INPUT;
outputSampleMetadata();
return Extractor.RESULT_END_OF_INPUT;
}
// Search for a frame.
@ -257,24 +269,17 @@ public final class FlacExtractor implements Extractor {
scratch.skipBytes(Math.min(minFrameSize, scratch.bytesLeft()));
}
int nextFrameBlockSizeSamples = findFrame(scratch, foundEndOfInput);
long nextFrameFirstSampleNumber = findFrame(scratch, foundEndOfInput);
int numberOfFrameBytes = scratch.getPosition() - positionBeforeFindingAFrame;
scratch.setPosition(positionBeforeFindingAFrame);
trackOutput.sampleData(scratch, numberOfFrameBytes);
currentFrameBytesWritten += numberOfFrameBytes;
// Frame found.
if (nextFrameBlockSizeSamples != BLOCK_SIZE_UNKNOWN || foundEndOfInput) {
long timeUs = getTimeUs(totalSamplesWritten, flacStreamMetadata.sampleRate);
trackOutput.sampleMetadata(
timeUs,
C.BUFFER_FLAG_KEY_FRAME,
currentFrameBytesWritten,
/* offset= */ 0,
/* encryptionData= */ null);
totalSamplesWritten += currentFrameBlockSizeSamples;
if (nextFrameFirstSampleNumber != SAMPLE_NUMBER_UNKNOWN) {
outputSampleMetadata();
currentFrameBytesWritten = 0;
currentFrameBlockSizeSamples = nextFrameBlockSizeSamples;
currentFrameFirstSampleNumber = nextFrameFirstSampleNumber;
}
if (scratch.bytesLeft() < FlacConstants.MAX_FRAME_HEADER_SIZE) {
@ -288,6 +293,21 @@ public final class FlacExtractor implements Extractor {
return Extractor.RESULT_CONTINUE;
}
private SeekMap getSeekMap(int firstFramePosition, long streamLength) {
Assertions.checkNotNull(flacStreamMetadata);
if (streamLength == C.LENGTH_UNSET || flacStreamMetadata.totalSamples == 0) {
return new SeekMap.Unseekable(flacStreamMetadata.getDurationUs());
}
binarySearchSeeker =
new FlacBinarySearchSeeker(
flacStreamMetadata,
frameStartMarker,
firstFramePosition,
streamLength,
sampleNumberHolder);
return binarySearchSeeker.getSeekMap();
}
/**
* Searches for the start of a frame in {@code scratch}.
*
@ -298,19 +318,19 @@ public final class FlacExtractor implements Extractor {
*
* @param scratch The array to be searched.
* @param foundEndOfInput If the end of input was met when filling in the {@code scratch}.
* @return The block size of the frame found, or {@code BLOCK_SIZE_UNKNOWN} if the search was not
* successful.
* @return The number of the first sample in the frame found, or {@code SAMPLE_NUMBER_UNKNOWN} if
* the search was not successful.
*/
private int findFrame(ParsableByteArray scratch, boolean foundEndOfInput) {
private long findFrame(ParsableByteArray scratch, boolean foundEndOfInput) {
Assertions.checkNotNull(flacStreamMetadata);
int frameOffset = scratch.getPosition();
while (frameOffset <= scratch.limit() - FlacConstants.MAX_FRAME_HEADER_SIZE) {
scratch.setPosition(frameOffset);
if (FlacFrameReader.checkAndReadFrameHeader(
scratch, flacStreamMetadata, frameStartMarker, blockSizeHolder)) {
scratch, flacStreamMetadata, frameStartMarker, sampleNumberHolder)) {
scratch.setPosition(frameOffset);
return blockSizeHolder.blockSizeSamples;
return sampleNumberHolder.sampleNumber;
}
frameOffset++;
}
@ -322,10 +342,20 @@ public final class FlacExtractor implements Extractor {
scratch.setPosition(frameOffset);
}
return BLOCK_SIZE_UNKNOWN;
return SAMPLE_NUMBER_UNKNOWN;
}
private long getTimeUs(long numSamples, int sampleRate) {
return numSamples * C.MICROS_PER_SECOND / sampleRate;
private void outputSampleMetadata() {
long timeUs =
currentFrameFirstSampleNumber
* C.MICROS_PER_SECOND
/ castNonNull(flacStreamMetadata).sampleRate;
castNonNull(trackOutput)
.sampleMetadata(
timeUs,
C.BUFFER_FLAG_KEY_FRAME,
currentFrameBytesWritten,
/* offset= */ 0,
/* encryptionData= */ null);
}
}

View File

@ -171,14 +171,14 @@ public final class FlacStreamMetadata {
}
/**
* Returns the sample index for the sample at given position.
* Returns the sample number of the sample at a given time.
*
* @param timeUs Time position in microseconds in the FLAC stream.
* @return The sample index for the sample at given position.
* @return The sample number corresponding to the time position.
*/
public long getSampleIndex(long timeUs) {
long sampleIndex = (timeUs * sampleRate) / C.MICROS_PER_SECOND;
return Util.constrainValue(sampleIndex, /* min= */ 0, totalSamples - 1);
public long getSampleNumber(long timeUs) {
long sampleNumber = (timeUs * sampleRate) / C.MICROS_PER_SECOND;
return Util.constrainValue(sampleNumber, /* min= */ 0, totalSamples - 1);
}
/** Returns the approximate number of bytes per frame for the current FLAC stream. */

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = -1
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 9218FDB7
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = -1
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 9218FDB7
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = -1
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 9218FDB7
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = -1
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 9218FDB7
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=42]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=42]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=42]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=42]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=8288]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,108 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8288]]
numberOfTracks = 1
track 0:
format:
bitrate = 1408000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 6456
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 44000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 7249A1B8
total output bytes = 100240
sample count = 19
sample 0:
time = 837818
flags = 1
data = length 5414, hash 90768345
sample 1:
time = 942545
flags = 1
data = length 5531, hash 1CD2FF67
sample 2:
time = 1047272
flags = 1
data = length 5870, hash A9A5CAEE
sample 3:
time = 1152000
flags = 1
data = length 5667, hash 875566A1
sample 4:
time = 1256727
flags = 1
data = length 5614, hash 5573694C
sample 5:
time = 1361454
flags = 1
data = length 6456, hash 921F3DE7
sample 6:
time = 1466181
flags = 1
data = length 5817, hash EBECBD16
sample 7:
time = 1570909
flags = 1
data = length 5751, hash 4A7D4C6B
sample 8:
time = 1675636
flags = 1
data = length 5620, hash B78F8E8D
sample 9:
time = 1780363
flags = 1
data = length 5535, hash 8187C107
sample 10:
time = 1885090
flags = 1
data = length 5517, hash 79FF36CB
sample 11:
time = 1989818
flags = 1
data = length 5716, hash 349FC281
sample 12:
time = 2094545
flags = 1
data = length 5556, hash BE97B2CA
sample 13:
time = 2199272
flags = 1
data = length 5703, hash 531F9FE3
sample 14:
time = 2304000
flags = 1
data = length 5652, hash 1277485D
sample 15:
time = 2408727
flags = 1
data = length 5607, hash 14862CB6
sample 16:
time = 2513454
flags = 1
data = length 5829, hash FCAF2F1C
sample 17:
time = 2618181
flags = 1
data = length 2837, hash 10F1716E
sample 18:
time = 2722909
flags = 1
data = length 548, hash B46F603C
tracksEnded = true

View File

@ -0,0 +1,72 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8288]]
numberOfTracks = 1
track 0:
format:
bitrate = 1408000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 6456
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 44000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 7249A1B8
total output bytes = 48500
sample count = 10
sample 0:
time = 1780363
flags = 1
data = length 5535, hash 8187C107
sample 1:
time = 1885090
flags = 1
data = length 5517, hash 79FF36CB
sample 2:
time = 1989818
flags = 1
data = length 5716, hash 349FC281
sample 3:
time = 2094545
flags = 1
data = length 5556, hash BE97B2CA
sample 4:
time = 2199272
flags = 1
data = length 5703, hash 531F9FE3
sample 5:
time = 2304000
flags = 1
data = length 5652, hash 1277485D
sample 6:
time = 2408727
flags = 1
data = length 5607, hash 14862CB6
sample 7:
time = 2513454
flags = 1
data = length 5829, hash FCAF2F1C
sample 8:
time = 2618181
flags = 1
data = length 2837, hash 10F1716E
sample 9:
time = 2722909
flags = 1
data = length 548, hash B46F603C
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8288]]
numberOfTracks = 1
track 0:
format:
bitrate = 1408000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 6456
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 44000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 7249A1B8
total output bytes = 548
sample count = 1
sample 0:
time = 2722909
flags = 1
data = length 548, hash B46F603C
tracksEnded = true

View File

@ -0,0 +1,140 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1408000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 6456
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 44000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 7249A1B8
total output bytes = 144086
sample count = 27
sample 0:
time = 0
flags = 1
data = length 5415, hash 915DBC66
sample 1:
time = 104727
flags = 1
data = length 5529, hash EFD564F7
sample 2:
time = 209454
flags = 1
data = length 5480, hash ADA922FB
sample 3:
time = 314181
flags = 1
data = length 5290, hash 7BCEA5FC
sample 4:
time = 418909
flags = 1
data = length 5579, hash DBB36F37
sample 5:
time = 523636
flags = 1
data = length 5423, hash AB53F799
sample 6:
time = 628363
flags = 1
data = length 5583, hash 7243C284
sample 7:
time = 733090
flags = 1
data = length 5547, hash 9DA9C99E
sample 8:
time = 837818
flags = 1
data = length 5414, hash 90768345
sample 9:
time = 942545
flags = 1
data = length 5531, hash 1CD2FF67
sample 10:
time = 1047272
flags = 1
data = length 5870, hash A9A5CAEE
sample 11:
time = 1152000
flags = 1
data = length 5667, hash 875566A1
sample 12:
time = 1256727
flags = 1
data = length 5614, hash 5573694C
sample 13:
time = 1361454
flags = 1
data = length 6456, hash 921F3DE7
sample 14:
time = 1466181
flags = 1
data = length 5817, hash EBECBD16
sample 15:
time = 1570909
flags = 1
data = length 5751, hash 4A7D4C6B
sample 16:
time = 1675636
flags = 1
data = length 5620, hash B78F8E8D
sample 17:
time = 1780363
flags = 1
data = length 5535, hash 8187C107
sample 18:
time = 1885090
flags = 1
data = length 5517, hash 79FF36CB
sample 19:
time = 1989818
flags = 1
data = length 5716, hash 349FC281
sample 20:
time = 2094545
flags = 1
data = length 5556, hash BE97B2CA
sample 21:
time = 2199272
flags = 1
data = length 5703, hash 531F9FE3
sample 22:
time = 2304000
flags = 1
data = length 5652, hash 1277485D
sample 23:
time = 2408727
flags = 1
data = length 5607, hash 14862CB6
sample 24:
time = 2513454
flags = 1
data = length 5829, hash FCAF2F1C
sample 25:
time = 2618181
flags = 1
data = length 2837, hash 10F1716E
sample 26:
time = 2722909
flags = 1
data = length 548, hash B46F603C
tracksEnded = true

View File

@ -0,0 +1,123 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,79 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,35 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,163 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = null
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[TXXX: description=ID: value=105519843, TIT2: description=null: value=那么爱你为什么, TPE1: description=null: value=阿强, TALB: description=null: value=华丽的外衣, TXXX: description=ID: value=105519843, APIC: mimeType=image/jpeg, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[TXXX: description=ID: value=105519843, TIT2: description=null: value=那么爱你为什么, TPE1: description=null: value=阿强, TALB: description=null: value=华丽的外衣, TXXX: description=ID: value=105519843, APIC: mimeType=image/jpeg, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=55284]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[TXXX: description=ID: value=105519843, TIT2: description=null: value=那么爱你为什么, TPE1: description=null: value=阿强, TALB: description=null: value=华丽的外衣, TXXX: description=ID: value=105519843, APIC: mimeType=image/jpeg, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[TXXX: description=ID: value=105519843, TIT2: description=null: value=那么爱你为什么, TPE1: description=null: value=阿强, TALB: description=null: value=华丽的外衣, TXXX: description=ID: value=105519843, APIC: mimeType=image/jpeg, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=39868]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=39868]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[Picture: mimeType=image/png, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=39868]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[Picture: mimeType=image/png, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=39868]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[Picture: mimeType=image/png, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[Picture: mimeType=image/png, description=]
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -1,7 +1,7 @@
seekMap:
isSeekable = false
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:

View File

@ -0,0 +1,124 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[VC: TITLE=test title, VC: ARTIST=test artist]
initializationData:
data = length 42, hash 83F6895
total output bytes = 113666
sample count = 23
sample 0:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 1:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 2:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 3:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 4:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 5:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 6:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 7:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 8:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 9:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 10:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 11:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 12:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 13:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 14:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 15:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 16:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 17:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 18:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 19:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 20:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 21:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 22:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,80 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[VC: TITLE=test title, VC: ARTIST=test artist]
initializationData:
data = length 42, hash 83F6895
total output bytes = 55652
sample count = 12
sample 0:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 1:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 2:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 3:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 4:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 5:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 6:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 7:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 8:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 9:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 10:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 11:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,36 @@
seekMap:
isSeekable = true
duration = 2741000
getPosition(0) = [[timeUs=0, position=8880]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[VC: TITLE=test title, VC: ARTIST=test artist]
initializationData:
data = length 42, hash 83F6895
total output bytes = 445
sample count = 1
sample 0:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -0,0 +1,164 @@
seekMap:
isSeekable = false
duration = 2741000
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
format:
bitrate = 1536000
id = null
containerMimeType = null
sampleMimeType = audio/flac
maxInputSize = 5776
width = -1
height = -1
frameRate = -1.0
rotationDegrees = 0
pixelWidthHeightRatio = 1.0
channelCount = 2
sampleRate = 48000
pcmEncoding = -1
encoderDelay = 0
encoderPadding = 0
subsampleOffsetUs = 9223372036854775807
selectionFlags = 0
language = null
drmInitData = -
metadata = entries=[VC: TITLE=test title, VC: ARTIST=test artist]
initializationData:
data = length 42, hash 83F6895
total output bytes = 164431
sample count = 33
sample 0:
time = 0
flags = 1
data = length 5030, hash D2B60530
sample 1:
time = 85333
flags = 1
data = length 5066, hash 4C932A54
sample 2:
time = 170666
flags = 1
data = length 5112, hash 7E5A7B61
sample 3:
time = 256000
flags = 1
data = length 5044, hash 7EF93F13
sample 4:
time = 341333
flags = 1
data = length 4943, hash DE7E27F8
sample 5:
time = 426666
flags = 1
data = length 5121, hash 6D0D0B40
sample 6:
time = 512000
flags = 1
data = length 5068, hash 9924644F
sample 7:
time = 597333
flags = 1
data = length 5143, hash 6C34F0CE
sample 8:
time = 682666
flags = 1
data = length 5109, hash E3B7BEFB
sample 9:
time = 768000
flags = 1
data = length 5129, hash 44111D9B
sample 10:
time = 853333
flags = 1
data = length 5031, hash 9D55EA53
sample 11:
time = 938666
flags = 1
data = length 5119, hash E1CB9BA6
sample 12:
time = 1024000
flags = 1
data = length 5360, hash 17265C5D
sample 13:
time = 1109333
flags = 1
data = length 5340, hash A90FDDF1
sample 14:
time = 1194666
flags = 1
data = length 5162, hash 31F65AD5
sample 15:
time = 1280000
flags = 1
data = length 5168, hash F2394F2D
sample 16:
time = 1365333
flags = 1
data = length 5776, hash 58437AB3
sample 17:
time = 1450666
flags = 1
data = length 5394, hash EBAB20A8
sample 18:
time = 1536000
flags = 1
data = length 5168, hash BF37C7A5
sample 19:
time = 1621333
flags = 1
data = length 5324, hash 59546B7B
sample 20:
time = 1706666
flags = 1
data = length 5172, hash 6036EF0B
sample 21:
time = 1792000
flags = 1
data = length 5102, hash 5A131071
sample 22:
time = 1877333
flags = 1
data = length 5111, hash 3D9EBB3B
sample 23:
time = 1962666
flags = 1
data = length 5113, hash 61101D4F
sample 24:
time = 2048000
flags = 1
data = length 5229, hash D2E55742
sample 25:
time = 2133333
flags = 1
data = length 5162, hash 7F2E97FA
sample 26:
time = 2218666
flags = 1
data = length 5255, hash D92A782
sample 27:
time = 2304000
flags = 1
data = length 5196, hash 98FE5138
sample 28:
time = 2389333
flags = 1
data = length 5214, hash 3D35C38C
sample 29:
time = 2474666
flags = 1
data = length 5211, hash 7E25420F
sample 30:
time = 2560000
flags = 1
data = length 5230, hash 2AD96FBC
sample 31:
time = 2645333
flags = 1
data = length 3384, hash 938BCDD9
sample 32:
time = 2730666
flags = 1
data = length 445, hash A388E3D6
tracksEnded = true

View File

@ -15,8 +15,14 @@
*/
package com.google.android.exoplayer2.extractor.flac;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -26,41 +32,41 @@ public class FlacExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear.flac");
assertBehavior(FlacExtractor::new, "flac/bear.flac");
}
@Test
public void testSampleWithId3HeaderAndId3Enabled() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear_with_id3_enabled.flac");
assertBehavior(FlacExtractor::new, "flac/bear_with_id3_enabled.flac");
}
@Test
public void testSampleWithId3HeaderAndId3Disabled() throws Exception {
// bear_with_id3_disabled.flac is identical to bear_with_id3_enabled.flac, but the dump file is
// different due to setting FLAG_DISABLE_ID3_METADATA.
ExtractorAsserts.assertBehavior(
assertBehavior(
() -> new FlacExtractor(FlacExtractor.FLAG_DISABLE_ID3_METADATA),
"flac/bear_with_id3_disabled.flac");
}
@Test
public void testSampleWithVorbisComments() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear_with_vorbis_comments.flac");
assertBehavior(FlacExtractor::new, "flac/bear_with_vorbis_comments.flac");
}
@Test
public void testSampleWithPicture() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear_with_picture.flac");
assertBehavior(FlacExtractor::new, "flac/bear_with_picture.flac");
}
@Test
public void testOneMetadataBlock() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear_one_metadata_block.flac");
assertBehavior(FlacExtractor::new, "flac/bear_one_metadata_block.flac");
}
@Test
public void testNoMinMaxFrameSize() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear_no_min_max_frame_size.flac");
assertBehavior(FlacExtractor::new, "flac/bear_no_min_max_frame_size.flac");
}
@Test
@ -70,6 +76,24 @@ public class FlacExtractorTest {
@Test
public void testUncommonSampleRate() throws Exception {
ExtractorAsserts.assertBehavior(FlacExtractor::new, "flac/bear_uncommon_sample_rate.flac");
assertBehavior(FlacExtractor::new, "flac/bear_uncommon_sample_rate.flac");
}
private void assertBehavior(ExtractorFactory factory, String file)
throws IOException, InterruptedException {
// Check behavior prior to initialization.
Extractor extractor = factory.create();
extractor.seek(0, 0);
extractor.release();
// Assert output.
Context context = ApplicationProvider.getApplicationContext();
byte[] data = TestUtil.getByteArray(context, file);
// Don't simulate IO errors as it is too slow (see b/145994869).
ExtractorAsserts.assertOutput(factory.create(), file, data, context, true, false, false, false);
ExtractorAsserts.assertOutput(factory.create(), file, data, context, true, false, false, true);
ExtractorAsserts.assertOutput(factory.create(), file, data, context, true, false, true, false);
ExtractorAsserts.assertOutput(factory.create(), file, data, context, true, false, true, true);
ExtractorAsserts.assertOutput(
factory.create(), file, data, context, false, false, false, false);
}
}

View File

@ -171,7 +171,7 @@ public final class ExtractorAsserts {
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
*/
private static FakeExtractorOutput assertOutput(
public static FakeExtractorOutput assertOutput(
Extractor extractor,
String file,
byte[] data,