Search in sources :

Example 41 with ParserException

use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.

the class VorbisUtilTest method testVerifyVorbisHeaderCapturePatternInvalidHeaderQuite.

public void testVerifyVorbisHeaderCapturePatternInvalidHeaderQuite() throws ParserException {
    ParsableByteArray header = new ParsableByteArray(new byte[] { 0x01, 'v', 'o', 'r', 'b', 'i', 's' });
    assertFalse(VorbisUtil.verifyVorbisHeaderCapturePattern(0x99, header, true));
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray)

Example 42 with ParserException

use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.

the class WavExtractor method read.

@Override
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException {
    if (wavHeader == null) {
        wavHeader = WavHeaderReader.peek(input);
        if (wavHeader == null) {
            // Should only happen if the media wasn't sniffed.
            throw new ParserException("Unsupported or unrecognized wav header.");
        }
        Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_RAW, null, wavHeader.getBitrate(), MAX_INPUT_SIZE, wavHeader.getNumChannels(), wavHeader.getSampleRateHz(), wavHeader.getEncoding(), null, null, 0, null);
        trackOutput.format(format);
        bytesPerFrame = wavHeader.getBytesPerFrame();
    }
    if (!wavHeader.hasDataBounds()) {
        WavHeaderReader.skipToData(input, wavHeader);
        extractorOutput.seekMap(this);
    }
    int bytesAppended = trackOutput.sampleData(input, MAX_INPUT_SIZE - pendingBytes, true);
    if (bytesAppended != RESULT_END_OF_INPUT) {
        pendingBytes += bytesAppended;
    }
    // Samples must consist of a whole number of frames.
    int pendingFrames = pendingBytes / bytesPerFrame;
    if (pendingFrames > 0) {
        long timeUs = wavHeader.getTimeUs(input.getPosition() - pendingBytes);
        int size = pendingFrames * bytesPerFrame;
        pendingBytes -= size;
        trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, size, pendingBytes, null);
    }
    return bytesAppended == RESULT_END_OF_INPUT ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
}
Also used : ParserException(com.google.android.exoplayer2.ParserException) Format(com.google.android.exoplayer2.Format)

Example 43 with ParserException

use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.

the class WavHeaderReader method skipToData.

/**
   * Skips to the data in the given WAV input stream and returns its data size. After calling, the
   * input stream's position will point to the start of sample data in the WAV.
   * <p>
   * If an exception is thrown, the input position will be left pointing to a chunk header.
   *
   * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to
   *     a valid chunk header.
   * @param wavHeader WAV header to populate with data bounds.
   * @throws ParserException If an error occurs parsing chunks.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from input.
   */
public static void skipToData(ExtractorInput input, WavHeader wavHeader) throws IOException, InterruptedException {
    Assertions.checkNotNull(input);
    Assertions.checkNotNull(wavHeader);
    // Make sure the peek position is set to the read position before we peek the first header.
    input.resetPeekPosition();
    ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
    // Skip all chunks until we hit the data header.
    ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
    while (chunkHeader.id != Util.getIntegerCodeForString("data")) {
        Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
        long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
        // Override size of RIFF chunk, since it describes its size as the entire file.
        if (chunkHeader.id == Util.getIntegerCodeForString("RIFF")) {
            bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
        }
        if (bytesToSkip > Integer.MAX_VALUE) {
            throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
        }
        input.skipFully((int) bytesToSkip);
        chunkHeader = ChunkHeader.peek(input, scratch);
    }
    // Skip past the "data" header.
    input.skipFully(ChunkHeader.SIZE_IN_BYTES);
    wavHeader.setDataBounds(input.getPosition(), chunkHeader.size);
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) ParserException(com.google.android.exoplayer2.ParserException)

Example 44 with ParserException

use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.

the class HlsPlaylistParser method parseMediaPlaylist.

private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String baseUri) throws IOException {
    @HlsMediaPlaylist.PlaylistType int playlistType = HlsMediaPlaylist.PLAYLIST_TYPE_UNKNOWN;
    long startOffsetUs = C.TIME_UNSET;
    int mediaSequence = 0;
    // Default version == 1.
    int version = 1;
    long targetDurationUs = C.TIME_UNSET;
    boolean hasEndTag = false;
    Segment initializationSegment = null;
    List<Segment> segments = new ArrayList<>();
    long segmentDurationUs = 0;
    boolean hasDiscontinuitySequence = false;
    int playlistDiscontinuitySequence = 0;
    int relativeDiscontinuitySequence = 0;
    long playlistStartTimeUs = 0;
    long segmentStartTimeUs = 0;
    long segmentByteRangeOffset = 0;
    long segmentByteRangeLength = C.LENGTH_UNSET;
    int segmentMediaSequence = 0;
    boolean isEncrypted = false;
    String encryptionKeyUri = null;
    String encryptionIV = null;
    String line;
    while (iterator.hasNext()) {
        line = iterator.next();
        if (line.startsWith(TAG_PLAYLIST_TYPE)) {
            String playlistTypeString = parseStringAttr(line, REGEX_PLAYLIST_TYPE);
            if ("VOD".equals(playlistTypeString)) {
                playlistType = HlsMediaPlaylist.PLAYLIST_TYPE_VOD;
            } else if ("EVENT".equals(playlistTypeString)) {
                playlistType = HlsMediaPlaylist.PLAYLIST_TYPE_EVENT;
            } else {
                throw new ParserException("Illegal playlist type: " + playlistTypeString);
            }
        } else if (line.startsWith(TAG_START)) {
            startOffsetUs = (long) (parseDoubleAttr(line, REGEX_TIME_OFFSET) * C.MICROS_PER_SECOND);
        } else if (line.startsWith(TAG_INIT_SEGMENT)) {
            String uri = parseStringAttr(line, REGEX_URI);
            String byteRange = parseOptionalStringAttr(line, REGEX_ATTR_BYTERANGE);
            if (byteRange != null) {
                String[] splitByteRange = byteRange.split("@");
                segmentByteRangeLength = Long.parseLong(splitByteRange[0]);
                if (splitByteRange.length > 1) {
                    segmentByteRangeOffset = Long.parseLong(splitByteRange[1]);
                }
            }
            initializationSegment = new Segment(uri, segmentByteRangeOffset, segmentByteRangeLength);
            segmentByteRangeOffset = 0;
            segmentByteRangeLength = C.LENGTH_UNSET;
        } else if (line.startsWith(TAG_TARGET_DURATION)) {
            targetDurationUs = parseIntAttr(line, REGEX_TARGET_DURATION) * C.MICROS_PER_SECOND;
        } else if (line.startsWith(TAG_MEDIA_SEQUENCE)) {
            mediaSequence = parseIntAttr(line, REGEX_MEDIA_SEQUENCE);
            segmentMediaSequence = mediaSequence;
        } else if (line.startsWith(TAG_VERSION)) {
            version = parseIntAttr(line, REGEX_VERSION);
        } else if (line.startsWith(TAG_MEDIA_DURATION)) {
            segmentDurationUs = (long) (parseDoubleAttr(line, REGEX_MEDIA_DURATION) * C.MICROS_PER_SECOND);
        } else if (line.startsWith(TAG_KEY)) {
            String method = parseStringAttr(line, REGEX_METHOD);
            isEncrypted = METHOD_AES128.equals(method);
            if (isEncrypted) {
                encryptionKeyUri = parseStringAttr(line, REGEX_URI);
                encryptionIV = parseOptionalStringAttr(line, REGEX_IV);
            } else {
                encryptionKeyUri = null;
                encryptionIV = null;
            }
        } else if (line.startsWith(TAG_BYTERANGE)) {
            String byteRange = parseStringAttr(line, REGEX_BYTERANGE);
            String[] splitByteRange = byteRange.split("@");
            segmentByteRangeLength = Long.parseLong(splitByteRange[0]);
            if (splitByteRange.length > 1) {
                segmentByteRangeOffset = Long.parseLong(splitByteRange[1]);
            }
        } else if (line.startsWith(TAG_DISCONTINUITY_SEQUENCE)) {
            hasDiscontinuitySequence = true;
            playlistDiscontinuitySequence = Integer.parseInt(line.substring(line.indexOf(':') + 1));
        } else if (line.equals(TAG_DISCONTINUITY)) {
            relativeDiscontinuitySequence++;
        } else if (line.startsWith(TAG_PROGRAM_DATE_TIME)) {
            if (playlistStartTimeUs == 0) {
                long programDatetimeUs = C.msToUs(Util.parseXsDateTime(line.substring(line.indexOf(':') + 1)));
                playlistStartTimeUs = programDatetimeUs - segmentStartTimeUs;
            }
        } else if (!line.startsWith("#")) {
            String segmentEncryptionIV;
            if (!isEncrypted) {
                segmentEncryptionIV = null;
            } else if (encryptionIV != null) {
                segmentEncryptionIV = encryptionIV;
            } else {
                segmentEncryptionIV = Integer.toHexString(segmentMediaSequence);
            }
            segmentMediaSequence++;
            if (segmentByteRangeLength == C.LENGTH_UNSET) {
                segmentByteRangeOffset = 0;
            }
            segments.add(new Segment(line, segmentDurationUs, relativeDiscontinuitySequence, segmentStartTimeUs, isEncrypted, encryptionKeyUri, segmentEncryptionIV, segmentByteRangeOffset, segmentByteRangeLength));
            segmentStartTimeUs += segmentDurationUs;
            segmentDurationUs = 0;
            if (segmentByteRangeLength != C.LENGTH_UNSET) {
                segmentByteRangeOffset += segmentByteRangeLength;
            }
            segmentByteRangeLength = C.LENGTH_UNSET;
        } else if (line.equals(TAG_ENDLIST)) {
            hasEndTag = true;
        }
    }
    return new HlsMediaPlaylist(playlistType, baseUri, startOffsetUs, playlistStartTimeUs, hasDiscontinuitySequence, playlistDiscontinuitySequence, mediaSequence, version, targetDurationUs, hasEndTag, playlistStartTimeUs != 0, initializationSegment, segments);
}
Also used : ParserException(com.google.android.exoplayer2.ParserException) ArrayList(java.util.ArrayList) Segment(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment)

Example 45 with ParserException

use of com.google.android.exoplayer2.ParserException in project ExoPlayer by google.

the class RawCcExtractor method parseTimestampAndSampleCount.

private boolean parseTimestampAndSampleCount(ExtractorInput input) throws IOException, InterruptedException {
    dataScratch.reset();
    if (version == 0) {
        if (!input.readFully(dataScratch.data, 0, TIMESTAMP_SIZE_V0 + 1, true)) {
            return false;
        }
        // version 0 timestamps are 45kHz, so we need to convert them into us
        timestampUs = dataScratch.readUnsignedInt() * 1000 / 45;
    } else if (version == 1) {
        if (!input.readFully(dataScratch.data, 0, TIMESTAMP_SIZE_V1 + 1, true)) {
            return false;
        }
        timestampUs = dataScratch.readLong();
    } else {
        throw new ParserException("Unsupported version number: " + version);
    }
    remainingSampleCount = dataScratch.readUnsignedByte();
    sampleBytesWritten = 0;
    return true;
}
Also used : ParserException(com.google.android.exoplayer2.ParserException)

Aggregations

ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)25 Test (org.junit.Test)25 ParserException (com.google.android.exoplayer2.ParserException)21 MediaItem (com.google.android.exoplayer2.MediaItem)13 Timeline (com.google.android.exoplayer2.Timeline)13 Nullable (androidx.annotation.Nullable)12 Format (com.google.android.exoplayer2.Format)7 PositionHolder (com.google.android.exoplayer2.extractor.PositionHolder)5 LeafAtom (com.google.android.exoplayer2.extractor.mp4.Atom.LeafAtom)5 FakeExtractorInput (com.google.android.exoplayer2.testutil.FakeExtractorInput)5 ArrayList (java.util.ArrayList)5 Uri (android.net.Uri)3 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)3 ContainerAtom (com.google.android.exoplayer2.extractor.mp4.Atom.ContainerAtom)3 RequiresNonNull (org.checkerframework.checker.nullness.qual.RequiresNonNull)3 CallSuper (androidx.annotation.CallSuper)2 AacUtil (com.google.android.exoplayer2.audio.AacUtil)2 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)2 GaplessInfoHolder (com.google.android.exoplayer2.extractor.GaplessInfoHolder)2 AvcConfig (com.google.android.exoplayer2.video.AvcConfig)2