Search in sources :

Example 66 with Cue

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

the class PgsDecoder method decode.

@Override
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
    buffer.reset(data, size);
    maybeInflateData(buffer);
    cueBuilder.reset();
    ArrayList<Cue> cues = new ArrayList<>();
    while (buffer.bytesLeft() >= 3) {
        Cue cue = readNextSection(buffer, cueBuilder);
        if (cue != null) {
            cues.add(cue);
        }
    }
    return new PgsSubtitle(Collections.unmodifiableList(cues));
}
Also used : Cue(com.google.android.exoplayer2.text.Cue) ArrayList(java.util.ArrayList)

Example 67 with Cue

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

the class SubripDecoder method decode.

@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset) {
    ArrayList<Cue> cues = new ArrayList<>();
    LongArray cueTimesUs = new LongArray();
    ParsableByteArray subripData = new ParsableByteArray(bytes, length);
    @Nullable String currentLine;
    while ((currentLine = subripData.readLine()) != null) {
        if (currentLine.length() == 0) {
            // Skip blank lines.
            continue;
        }
        // Parse and check the index line.
        try {
            Integer.parseInt(currentLine);
        } catch (NumberFormatException e) {
            Log.w(TAG, "Skipping invalid index: " + currentLine);
            continue;
        }
        // Read and parse the timing line.
        currentLine = subripData.readLine();
        if (currentLine == null) {
            Log.w(TAG, "Unexpected end");
            break;
        }
        Matcher matcher = SUBRIP_TIMING_LINE.matcher(currentLine);
        if (matcher.matches()) {
            cueTimesUs.add(parseTimecode(matcher, /* groupOffset= */
            1));
            cueTimesUs.add(parseTimecode(matcher, /* groupOffset= */
            6));
        } else {
            Log.w(TAG, "Skipping invalid timing: " + currentLine);
            continue;
        }
        // Read and parse the text and tags.
        textBuilder.setLength(0);
        tags.clear();
        currentLine = subripData.readLine();
        while (!TextUtils.isEmpty(currentLine)) {
            if (textBuilder.length() > 0) {
                textBuilder.append("<br>");
            }
            textBuilder.append(processLine(currentLine, tags));
            currentLine = subripData.readLine();
        }
        Spanned text = Html.fromHtml(textBuilder.toString());
        @Nullable String alignmentTag = null;
        for (int i = 0; i < tags.size(); i++) {
            String tag = tags.get(i);
            if (tag.matches(SUBRIP_ALIGNMENT_TAG)) {
                alignmentTag = tag;
                // Subsequent alignment tags should be ignored.
                break;
            }
        }
        cues.add(buildCue(text, alignmentTag));
        cues.add(Cue.EMPTY);
    }
    Cue[] cuesArray = cues.toArray(new Cue[0]);
    long[] cueTimesUsArray = cueTimesUs.toArray();
    return new SubripSubtitle(cuesArray, cueTimesUsArray);
}
Also used : Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) Spanned(android.text.Spanned) LongArray(com.google.android.exoplayer2.util.LongArray) ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) Cue(com.google.android.exoplayer2.text.Cue) Nullable(androidx.annotation.Nullable)

Example 68 with Cue

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

the class TtmlNode method getCues.

public List<Cue> getCues(long timeUs, Map<String, TtmlStyle> globalStyles, Map<String, TtmlRegion> regionMap, Map<String, String> imageMap) {
    List<Pair<String, String>> regionImageOutputs = new ArrayList<>();
    traverseForImage(timeUs, regionId, regionImageOutputs);
    TreeMap<String, Cue.Builder> regionTextOutputs = new TreeMap<>();
    traverseForText(timeUs, false, regionId, regionTextOutputs);
    traverseForStyle(timeUs, globalStyles, regionMap, regionId, regionTextOutputs);
    List<Cue> cues = new ArrayList<>();
    // Create image based cues.
    for (Pair<String, String> regionImagePair : regionImageOutputs) {
        @Nullable String encodedBitmapData = imageMap.get(regionImagePair.second);
        if (encodedBitmapData == null) {
            // Image reference points to an invalid image. Do nothing.
            continue;
        }
        byte[] bitmapData = Base64.decode(encodedBitmapData, Base64.DEFAULT);
        Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, /* offset= */
        0, bitmapData.length);
        TtmlRegion region = Assertions.checkNotNull(regionMap.get(regionImagePair.first));
        cues.add(new Cue.Builder().setBitmap(bitmap).setPosition(region.position).setPositionAnchor(Cue.ANCHOR_TYPE_START).setLine(region.line, Cue.LINE_TYPE_FRACTION).setLineAnchor(region.lineAnchor).setSize(region.width).setBitmapHeight(region.height).setVerticalType(region.verticalType).build());
    }
    // Create text based cues.
    for (Map.Entry<String, Cue.Builder> entry : regionTextOutputs.entrySet()) {
        TtmlRegion region = Assertions.checkNotNull(regionMap.get(entry.getKey()));
        Cue.Builder regionOutput = entry.getValue();
        cleanUpText((SpannableStringBuilder) Assertions.checkNotNull(regionOutput.getText()));
        regionOutput.setLine(region.line, region.lineType);
        regionOutput.setLineAnchor(region.lineAnchor);
        regionOutput.setPosition(region.position);
        regionOutput.setSize(region.width);
        regionOutput.setTextSize(region.textSize, region.textSizeType);
        regionOutput.setVerticalType(region.verticalType);
        cues.add(regionOutput.build());
    }
    return cues;
}
Also used : SpannableStringBuilder(android.text.SpannableStringBuilder) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) Cue(com.google.android.exoplayer2.text.Cue) Bitmap(android.graphics.Bitmap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) Map(java.util.Map) Nullable(androidx.annotation.Nullable) Pair(android.util.Pair)

Example 69 with Cue

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

the class WebvttDecoder method decode.

@Override
protected Subtitle decode(byte[] bytes, int length, boolean reset) throws SubtitleDecoderException {
    parsableWebvttData.reset(bytes, length);
    List<WebvttCssStyle> definedStyles = new ArrayList<>();
    // Validate the first line of the header, and skip the remainder.
    try {
        WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
    } catch (ParserException e) {
        throw new SubtitleDecoderException(e);
    }
    while (!TextUtils.isEmpty(parsableWebvttData.readLine())) {
    }
    int event;
    List<WebvttCueInfo> cueInfos = new ArrayList<>();
    while ((event = getNextEvent(parsableWebvttData)) != EVENT_END_OF_FILE) {
        if (event == EVENT_COMMENT) {
            skipComment(parsableWebvttData);
        } else if (event == EVENT_STYLE_BLOCK) {
            if (!cueInfos.isEmpty()) {
                throw new SubtitleDecoderException("A style block was found after the first cue.");
            }
            // Consume the "STYLE" header.
            parsableWebvttData.readLine();
            definedStyles.addAll(cssParser.parseBlock(parsableWebvttData));
        } else if (event == EVENT_CUE) {
            @Nullable WebvttCueInfo cueInfo = WebvttCueParser.parseCue(parsableWebvttData, definedStyles);
            if (cueInfo != null) {
                cueInfos.add(cueInfo);
            }
        }
    }
    return new WebvttSubtitle(cueInfos);
}
Also used : ParserException(com.google.android.exoplayer2.ParserException) ArrayList(java.util.ArrayList) Nullable(androidx.annotation.Nullable) SubtitleDecoderException(com.google.android.exoplayer2.text.SubtitleDecoderException)

Example 70 with Cue

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

the class WebvttSubtitle method getCues.

@Override
public List<Cue> getCues(long timeUs) {
    List<Cue> currentCues = new ArrayList<>();
    List<WebvttCueInfo> cuesWithUnsetLine = new ArrayList<>();
    for (int i = 0; i < cueInfos.size(); i++) {
        if ((cueTimesUs[i * 2] <= timeUs) && (timeUs < cueTimesUs[i * 2 + 1])) {
            WebvttCueInfo cueInfo = cueInfos.get(i);
            if (cueInfo.cue.line == Cue.DIMEN_UNSET) {
                cuesWithUnsetLine.add(cueInfo);
            } else {
                currentCues.add(cueInfo.cue);
            }
        }
    }
    // Steps 4 - 10 of https://www.w3.org/TR/webvtt1/#cue-computed-line
    // (steps 1 - 3 are handled by WebvttCueParser#computeLine(float, int))
    Collections.sort(cuesWithUnsetLine, (c1, c2) -> Long.compare(c1.startTimeUs, c2.startTimeUs));
    for (int i = 0; i < cuesWithUnsetLine.size(); i++) {
        Cue cue = cuesWithUnsetLine.get(i).cue;
        currentCues.add(cue.buildUpon().setLine((float) (-1 - i), Cue.LINE_TYPE_NUMBER).build());
    }
    return currentCues;
}
Also used : Cue(com.google.android.exoplayer2.text.Cue) ArrayList(java.util.ArrayList)

Aggregations

Cue (com.google.android.exoplayer2.text.Cue)58 Test (org.junit.Test)40 Subtitle (com.google.android.exoplayer2.text.Subtitle)13 ArrayList (java.util.ArrayList)12 Nullable (androidx.annotation.Nullable)10 Spanned (android.text.Spanned)8 SpannableStringBuilder (android.text.SpannableStringBuilder)7 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)5 FakeExtractorOutput (com.google.android.exoplayer2.testutil.FakeExtractorOutput)4 SpannableString (android.text.SpannableString)3 UnderlineSpan (android.text.style.UnderlineSpan)3 Format (com.google.android.exoplayer2.Format)3 AdPlaybackState (com.google.android.exoplayer2.source.ads.AdPlaybackState)3 FakeExtractorInput (com.google.android.exoplayer2.testutil.FakeExtractorInput)3 FakeTrackOutput (com.google.android.exoplayer2.testutil.FakeTrackOutput)3 HorizontalTextInVerticalContextSpan (com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan)3 RubySpan (com.google.android.exoplayer2.text.span.RubySpan)3 TextEmphasisSpan (com.google.android.exoplayer2.text.span.TextEmphasisSpan)3 WebvttDecoder (com.google.android.exoplayer2.text.webvtt.WebvttDecoder)3 Matcher (java.util.regex.Matcher)3