use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.
the class FlacMetadataReader method readStreamMarker.
/**
* Reads the FLAC stream marker.
*
* @param input Input stream to read the stream marker from.
* @throws ParserException If an error occurs parsing the stream marker. In this case, the
* position of {@code input} is advanced by {@link FlacConstants#STREAM_MARKER_SIZE} bytes.
* @throws IOException If reading from the input fails. In this case, the position is left
* unchanged.
*/
public static void readStreamMarker(ExtractorInput input) throws IOException {
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
input.readFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
if (scratch.readUnsignedInt() != STREAM_MARKER) {
throw ParserException.createForMalformedContainer("Failed to read FLAC stream marker.", /* cause= */
null);
}
}
use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.
the class FlacMetadataReader method readMetadataBlock.
/**
* Reads one FLAC metadata block.
*
* <p>If no exception is thrown, the peek position of {@code input} is aligned with the read
* position.
*
* @param input Input stream to read the metadata block from (header included).
* @param metadataHolder A holder for the metadata read. If the stream info block (which must be
* the first metadata block) is read, the holder contains a new instance representing the
* stream info data. If the block read is a Vorbis comment block or a picture block, the
* holder contains a copy of the existing stream metadata with the corresponding metadata
* added. Otherwise, the metadata in the holder is unchanged.
* @return Whether the block read is the last metadata block.
* @throws IllegalArgumentException If the block read is not a stream info block and the metadata
* in {@code metadataHolder} is {@code null}. In this case, the read position will be at the
* start of a metadata block and there is no guarantee on the peek position.
* @throws IOException If reading from the input fails. In this case, the read position will be at
* the start of a metadata block and there is no guarantee on the peek position.
*/
public static boolean readMetadataBlock(ExtractorInput input, FlacStreamMetadataHolder metadataHolder) throws IOException {
input.resetPeekPosition();
ParsableBitArray scratch = new ParsableBitArray(new byte[4]);
input.peekFully(scratch.data, 0, FlacConstants.METADATA_BLOCK_HEADER_SIZE);
boolean isLastMetadataBlock = scratch.readBit();
int type = scratch.readBits(7);
int length = FlacConstants.METADATA_BLOCK_HEADER_SIZE + scratch.readBits(24);
if (type == FlacConstants.METADATA_TYPE_STREAM_INFO) {
metadataHolder.flacStreamMetadata = readStreamInfoBlock(input);
} else {
@Nullable FlacStreamMetadata flacStreamMetadata = metadataHolder.flacStreamMetadata;
if (flacStreamMetadata == null) {
throw new IllegalArgumentException();
}
if (type == FlacConstants.METADATA_TYPE_SEEK_TABLE) {
FlacStreamMetadata.SeekTable seekTable = readSeekTableMetadataBlock(input, length);
metadataHolder.flacStreamMetadata = flacStreamMetadata.copyWithSeekTable(seekTable);
} else if (type == FlacConstants.METADATA_TYPE_VORBIS_COMMENT) {
List<String> vorbisComments = readVorbisCommentMetadataBlock(input, length);
metadataHolder.flacStreamMetadata = flacStreamMetadata.copyWithVorbisComments(vorbisComments);
} else if (type == FlacConstants.METADATA_TYPE_PICTURE) {
ParsableByteArray pictureBlock = new ParsableByteArray(length);
input.readFully(pictureBlock.getData(), 0, length);
pictureBlock.skipBytes(FlacConstants.METADATA_BLOCK_HEADER_SIZE);
PictureFrame pictureFrame = PictureFrame.fromPictureBlock(pictureBlock);
metadataHolder.flacStreamMetadata = flacStreamMetadata.copyWithPictureFrames(ImmutableList.of(pictureFrame));
} else {
input.skipFully(length);
}
}
return isLastMetadataBlock;
}
use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.
the class FlacMetadataReader method readId3Metadata.
/**
* Reads ID3 Data.
*
* <p>If no exception is thrown, the peek position of {@code input} is aligned with the read
* position.
*
* @param input Input stream to read 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 reading from the input fails. In this case, the read position is left
* unchanged and there is no guarantee on the peek position.
*/
@Nullable
public static Metadata readId3Metadata(ExtractorInput input, boolean parseData) throws IOException {
input.resetPeekPosition();
long startingPeekPosition = input.getPeekPosition();
@Nullable Metadata id3Metadata = peekId3Metadata(input, parseData);
int peekedId3Bytes = (int) (input.getPeekPosition() - startingPeekPosition);
input.skipFully(peekedId3Bytes);
return id3Metadata;
}
use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.
the class FlacMetadataReader method readVorbisCommentMetadataBlock.
private static List<String> readVorbisCommentMetadataBlock(ExtractorInput input, int length) throws IOException {
ParsableByteArray scratch = new ParsableByteArray(length);
input.readFully(scratch.getData(), 0, length);
scratch.skipBytes(FlacConstants.METADATA_BLOCK_HEADER_SIZE);
CommentHeader commentHeader = VorbisUtil.readVorbisCommentHeader(scratch, /* hasMetadataHeader= */
false, /* hasFramingBit= */
false);
return Arrays.asList(commentHeader.comments);
}
use of com.google.android.exoplayer2.extractor.ExtractorInput in project ExoPlayer by google.
the class FlacMetadataReader method getFrameStartMarker.
/**
* 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 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.
*/
public static int getFrameStartMarker(ExtractorInput input) throws IOException {
input.resetPeekPosition();
ParsableByteArray scratch = new ParsableByteArray(2);
input.peekFully(scratch.getData(), 0, 2);
int frameStartMarker = scratch.readUnsignedShort();
int syncCode = frameStartMarker >> 2;
if (syncCode != SYNC_CODE) {
input.resetPeekPosition();
throw ParserException.createForMalformedContainer("First frame does not start with sync code.", /* cause= */
null);
}
input.resetPeekPosition();
return frameStartMarker;
}
Aggregations