Search in sources :

Example 61 with ExtractorInput

use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.

the class FlacFrameReader method getFirstSampleNumber.

/**
 * Returns the number of the first sample in the given frame.
 *
 * <p>The read position of {@code input} is left unchanged.
 *
 * <p>If no exception is thrown, the peek position is aligned with the read position. Otherwise,
 * there is no guarantee on the peek position.
 *
 * @param input Input stream to get the sample number from (starting from the read position).
 * @return The frame first sample number.
 * @throws ParserException If an error occurs parsing the sample number.
 * @throws IOException If peeking from the input fails.
 */
public static long getFirstSampleNumber(ExtractorInput input, FlacStreamMetadata flacStreamMetadata) throws IOException {
    input.resetPeekPosition();
    input.advancePeekPosition(1);
    byte[] blockingStrategyByte = new byte[1];
    input.peekFully(blockingStrategyByte, 0, 1);
    boolean isBlockSizeVariable = (blockingStrategyByte[0] & 1) == 1;
    input.advancePeekPosition(2);
    int maxUtf8SampleNumberSize = isBlockSizeVariable ? 7 : 6;
    ParsableByteArray scratch = new ParsableByteArray(maxUtf8SampleNumberSize);
    int totalBytesPeeked = ExtractorUtil.peekToLength(input, scratch.getData(), 0, maxUtf8SampleNumberSize);
    scratch.setLimit(totalBytesPeeked);
    input.resetPeekPosition();
    SampleNumberHolder sampleNumberHolder = new SampleNumberHolder();
    if (!checkAndReadFirstSampleNumber(scratch, flacStreamMetadata, isBlockSizeVariable, sampleNumberHolder)) {
        throw ParserException.createForMalformedContainer(/* message= */
        null, /* cause= */
        null);
    }
    return sampleNumberHolder.sampleNumber;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray)

Example 62 with ExtractorInput

use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.

the class Id3Peeker method peekId3Data.

/**
 * Peeks ID3 data from the input and parses the first ID3 tag.
 *
 * @param input The {@link ExtractorInput} from which data should be peeked.
 * @param id3FramePredicate Determines which ID3 frames are decoded. May be null to decode all
 *     frames.
 * @return The first ID3 tag decoded into a {@link Metadata} object. May be null if ID3 tag is not
 *     present in the input.
 * @throws IOException If an error occurred peeking from the input.
 */
@Nullable
public Metadata peekId3Data(ExtractorInput input, @Nullable Id3Decoder.FramePredicate id3FramePredicate) throws IOException {
    int peekedId3Bytes = 0;
    @Nullable Metadata metadata = null;
    while (true) {
        try {
            input.peekFully(scratch.getData(), /* offset= */
            0, Id3Decoder.ID3_HEADER_LENGTH);
        } catch (EOFException e) {
            // If input has less than ID3_HEADER_LENGTH, ignore the rest.
            break;
        }
        scratch.setPosition(0);
        if (scratch.readUnsignedInt24() != Id3Decoder.ID3_TAG) {
            // Not an ID3 tag.
            break;
        }
        // Skip major version, minor version and flags.
        scratch.skipBytes(3);
        int framesLength = scratch.readSynchSafeInt();
        int tagLength = Id3Decoder.ID3_HEADER_LENGTH + framesLength;
        if (metadata == null) {
            byte[] id3Data = new byte[tagLength];
            System.arraycopy(scratch.getData(), 0, id3Data, 0, Id3Decoder.ID3_HEADER_LENGTH);
            input.peekFully(id3Data, Id3Decoder.ID3_HEADER_LENGTH, framesLength);
            metadata = new Id3Decoder(id3FramePredicate).decode(id3Data, tagLength);
        } else {
            input.advancePeekPosition(framesLength);
        }
        peekedId3Bytes += tagLength;
    }
    input.resetPeekPosition();
    input.advancePeekPosition(peekedId3Bytes);
    return metadata;
}
Also used : Metadata(com.google.android.exoplayer2.metadata.Metadata) EOFException(java.io.EOFException) Id3Decoder(com.google.android.exoplayer2.metadata.id3.Id3Decoder) Nullable(androidx.annotation.Nullable) Nullable(androidx.annotation.Nullable)

Example 63 with ExtractorInput

use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.

the class FlacMetadataReader method peekId3Metadata.

/**
 * Peeks ID3 Data.
 *
 * @param input Input stream to peek the ID3 data from.
 * @param parseData Whether to parse the ID3 frames.
 * @return The parsed ID3 data, or {@code null} if there is no such data or if {@code parseData}
 *     is {@code false}.
 * @throws IOException If peeking from the input fails. In this case, there is no guarantee on the
 *     peek position.
 */
@Nullable
public static Metadata peekId3Metadata(ExtractorInput input, boolean parseData) throws IOException {
    @Nullable Id3Decoder.FramePredicate id3FramePredicate = parseData ? null : Id3Decoder.NO_FRAMES_PREDICATE;
    @Nullable Metadata id3Metadata = new Id3Peeker().peekId3Data(input, id3FramePredicate);
    return id3Metadata == null || id3Metadata.length() == 0 ? null : id3Metadata;
}
Also used : Metadata(com.google.android.exoplayer2.metadata.Metadata) Id3Decoder(com.google.android.exoplayer2.metadata.id3.Id3Decoder) Nullable(androidx.annotation.Nullable) Nullable(androidx.annotation.Nullable)

Example 64 with ExtractorInput

use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.

the class FlacMetadataReader method checkAndPeekStreamMarker.

/**
 * Peeks the FLAC stream marker.
 *
 * @param input Input stream to peek the stream marker from.
 * @return Whether the data peeked is the FLAC stream marker.
 * @throws IOException If peeking from the input fails. In this case, the peek position is left
 *     unchanged.
 */
public static boolean checkAndPeekStreamMarker(ExtractorInput input) throws IOException {
    ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
    input.peekFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
    return scratch.readUnsignedInt() == STREAM_MARKER;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray)

Example 65 with ExtractorInput

use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.

the class FlacMetadataReader method readSeekTableMetadataBlock.

private static FlacStreamMetadata.SeekTable readSeekTableMetadataBlock(ExtractorInput input, int length) throws IOException {
    ParsableByteArray scratch = new ParsableByteArray(length);
    input.readFully(scratch.getData(), 0, length);
    return readSeekTableMetadataBlock(scratch);
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray)

Aggregations

FakeExtractorInput (com.google.android.exoplayer2.testutil.FakeExtractorInput)85 Test (org.junit.Test)71 ExtractorInput (com.google.android.exoplayer2.extractor.ExtractorInput)53 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)39 FlacStreamMetadataHolder (com.google.android.exoplayer2.extractor.FlacMetadataReader.FlacStreamMetadataHolder)20 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)17 DefaultExtractorInput (com.google.android.exoplayer2.extractor.DefaultExtractorInput)16 Nullable (androidx.annotation.Nullable)15 Metadata (com.google.android.exoplayer2.metadata.Metadata)13 SampleNumberHolder (com.google.android.exoplayer2.extractor.FlacFrameReader.SampleNumberHolder)9 FakeDataSource (com.google.android.exoplayer2.testutil.FakeDataSource)9 EOFException (java.io.EOFException)8 SeekPoint (com.google.android.exoplayer2.extractor.SeekPoint)7 RequiresNonNull (org.checkerframework.checker.nullness.qual.RequiresNonNull)7 ParserException (com.google.android.exoplayer2.ParserException)5 SeekMap (com.google.android.exoplayer2.extractor.SeekMap)5 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)5 IOException (java.io.IOException)5 PositionHolder (com.google.android.exoplayer2.extractor.PositionHolder)3 Id3Decoder (com.google.android.exoplayer2.metadata.id3.Id3Decoder)3