Search in sources :

Example 11 with SubtitleDecoderException

use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.

the class Mp4WebvttDecoderTest method testTwoCuesSample.

public void testTwoCuesSample() throws SubtitleDecoderException {
    Mp4WebvttDecoder decoder = new Mp4WebvttDecoder();
    Subtitle result = decoder.decode(DOUBLE_CUE_SAMPLE, DOUBLE_CUE_SAMPLE.length);
    Cue firstExpectedCue = new Cue("Hello World");
    Cue secondExpectedCue = new Cue("Bye Bye");
    assertMp4WebvttSubtitleEquals(result, firstExpectedCue, secondExpectedCue);
}
Also used : Subtitle(com.google.android.exoplayer2.text.Subtitle) Cue(com.google.android.exoplayer2.text.Cue)

Example 12 with SubtitleDecoderException

use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.

the class WebvttExtractor method processSample.

private void processSample() throws ParserException {
    ParsableByteArray webvttData = new ParsableByteArray(sampleData);
    // Validate the first line of the header.
    try {
        WebvttParserUtil.validateWebvttHeaderLine(webvttData);
    } catch (SubtitleDecoderException e) {
        throw new ParserException(e);
    }
    // Defaults to use if the header doesn't contain an X-TIMESTAMP-MAP header.
    long vttTimestampUs = 0;
    long tsTimestampUs = 0;
    // Parse the remainder of the header looking for X-TIMESTAMP-MAP.
    String line;
    while (!TextUtils.isEmpty(line = webvttData.readLine())) {
        if (line.startsWith("X-TIMESTAMP-MAP")) {
            Matcher localTimestampMatcher = LOCAL_TIMESTAMP.matcher(line);
            if (!localTimestampMatcher.find()) {
                throw new ParserException("X-TIMESTAMP-MAP doesn't contain local timestamp: " + line);
            }
            Matcher mediaTimestampMatcher = MEDIA_TIMESTAMP.matcher(line);
            if (!mediaTimestampMatcher.find()) {
                throw new ParserException("X-TIMESTAMP-MAP doesn't contain media timestamp: " + line);
            }
            vttTimestampUs = WebvttParserUtil.parseTimestampUs(localTimestampMatcher.group(1));
            tsTimestampUs = TimestampAdjuster.ptsToUs(Long.parseLong(mediaTimestampMatcher.group(1)));
        }
    }
    // Find the first cue header and parse the start time.
    Matcher cueHeaderMatcher = WebvttParserUtil.findNextCueHeader(webvttData);
    if (cueHeaderMatcher == null) {
        // No cues found. Don't output a sample, but still output a corresponding track.
        buildTrackOutput(0);
        return;
    }
    long firstCueTimeUs = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1));
    long sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(firstCueTimeUs + tsTimestampUs - vttTimestampUs);
    long subsampleOffsetUs = sampleTimeUs - firstCueTimeUs;
    // Output the track.
    TrackOutput trackOutput = buildTrackOutput(subsampleOffsetUs);
    // Output the sample.
    sampleDataWrapper.reset(sampleData, sampleSize);
    trackOutput.sampleData(sampleDataWrapper, sampleSize);
    trackOutput.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) ParserException(com.google.android.exoplayer2.ParserException) Matcher(java.util.regex.Matcher) TrackOutput(com.google.android.exoplayer2.extractor.TrackOutput) SubtitleDecoderException(com.google.android.exoplayer2.text.SubtitleDecoderException)

Example 13 with SubtitleDecoderException

use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.

the class CeaDecoder method dequeueOutputBuffer.

@Override
public SubtitleOutputBuffer dequeueOutputBuffer() throws SubtitleDecoderException {
    if (availableOutputBuffers.isEmpty()) {
        return null;
    }
    // be deferred until they would be applicable
    while (!queuedInputBuffers.isEmpty() && queuedInputBuffers.first().timeUs <= playbackPositionUs) {
        SubtitleInputBuffer inputBuffer = queuedInputBuffers.pollFirst();
        // return immediately with an output buffer propagating that
        if (inputBuffer.isEndOfStream()) {
            SubtitleOutputBuffer outputBuffer = availableOutputBuffers.pollFirst();
            outputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
            releaseInputBuffer(inputBuffer);
            return outputBuffer;
        }
        decode(inputBuffer);
        // check if we have any caption updates to report
        if (isNewSubtitleDataAvailable()) {
            // Even if the subtitle is decode-only; we need to generate it to consume the data so it
            // isn't accidentally prepended to the next subtitle
            Subtitle subtitle = createSubtitle();
            if (!inputBuffer.isDecodeOnly()) {
                SubtitleOutputBuffer outputBuffer = availableOutputBuffers.pollFirst();
                outputBuffer.setContent(inputBuffer.timeUs, subtitle, Format.OFFSET_SAMPLE_RELATIVE);
                releaseInputBuffer(inputBuffer);
                return outputBuffer;
            }
        }
        releaseInputBuffer(inputBuffer);
    }
    return null;
}
Also used : Subtitle(com.google.android.exoplayer2.text.Subtitle) SubtitleInputBuffer(com.google.android.exoplayer2.text.SubtitleInputBuffer) SubtitleOutputBuffer(com.google.android.exoplayer2.text.SubtitleOutputBuffer)

Example 14 with SubtitleDecoderException

use of com.google.android.exoplayer2.text.SubtitleDecoderException in project ExoPlayer by google.

the class WebvttDecoder method decode.

@Override
protected WebvttSubtitle decode(byte[] bytes, int length) throws SubtitleDecoderException {
    parsableWebvttData.reset(bytes, length);
    // Initialization for consistent starting state.
    webvttCueBuilder.reset();
    definedStyles.clear();
    // Validate the first line of the header, and skip the remainder.
    WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
    while (!TextUtils.isEmpty(parsableWebvttData.readLine())) {
    }
    int event;
    ArrayList<WebvttCue> subtitles = new ArrayList<>();
    while ((event = getNextEvent(parsableWebvttData)) != EVENT_END_OF_FILE) {
        if (event == EVENT_COMMENT) {
            skipComment(parsableWebvttData);
        } else if (event == EVENT_STYLE_BLOCK) {
            if (!subtitles.isEmpty()) {
                throw new SubtitleDecoderException("A style block was found after the first cue.");
            }
            // Consume the "STYLE" header.
            parsableWebvttData.readLine();
            WebvttCssStyle styleBlock = cssParser.parseBlock(parsableWebvttData);
            if (styleBlock != null) {
                definedStyles.add(styleBlock);
            }
        } else if (event == EVENT_CUE) {
            if (cueParser.parseCue(parsableWebvttData, webvttCueBuilder, definedStyles)) {
                subtitles.add(webvttCueBuilder.build());
                webvttCueBuilder.reset();
            }
        }
    }
    return new WebvttSubtitle(subtitles);
}
Also used : ArrayList(java.util.ArrayList) SubtitleDecoderException(com.google.android.exoplayer2.text.SubtitleDecoderException)

Aggregations

Cue (com.google.android.exoplayer2.text.Cue)7 SubtitleDecoderException (com.google.android.exoplayer2.text.SubtitleDecoderException)5 SpannableStringBuilder (android.text.SpannableStringBuilder)4 Subtitle (com.google.android.exoplayer2.text.Subtitle)4 Matcher (java.util.regex.Matcher)3 ParserException (com.google.android.exoplayer2.ParserException)1 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)1 SubtitleInputBuffer (com.google.android.exoplayer2.text.SubtitleInputBuffer)1 SubtitleOutputBuffer (com.google.android.exoplayer2.text.SubtitleOutputBuffer)1 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 XmlPullParser (org.xmlpull.v1.XmlPullParser)1 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)1