Merge pull request #4178 from danybony:subtitle_color_in_cue_class

PiperOrigin-RevId: 295548715
This commit is contained in:
Ian Baker 2020-02-17 17:14:28 +00:00
commit 4e4a87f352
3 changed files with 110 additions and 0 deletions

View File

@ -41,6 +41,11 @@
(rendering is coming later).
* Fix `SubtitlePainter` to render `EDGE_TYPE_OUTLINE` using the correct color
([#6724](https://github.com/google/ExoPlayer/pull/6724)).
* Add support for WebVTT default
[text](https://www.w3.org/TR/webvtt1/#default-text-color) and
[background](https://www.w3.org/TR/webvtt1/#default-text-background) colors
([PR #4178](https://github.com/google/ExoPlayer/pull/4178),
[issue #6581](https://github.com/google/ExoPlayer/issues/6581)).
* DRM: Add support for attaching DRM sessions to clear content in the demo app.
* Downloads: Merge downloads in `SegmentDownloader` to improve overall download
speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)).

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.text.webvtt;
import static com.google.android.exoplayer2.text.SpanUtil.addOrReplaceSpan;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.SpannableStringBuilder;
@ -48,7 +49,9 @@ import java.lang.annotation.Retention;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -137,6 +140,44 @@ public final class WebvttCueParser {
private static final String TAG = "WebvttCueParser";
/**
* See WebVTT's <a href="https://www.w3.org/TR/webvtt1/#default-text-color">default text
* colors</a>.
*/
private static final Map<String, Integer> DEFAULT_TEXT_COLORS;
static {
Map<String, Integer> defaultColors = new HashMap<>();
defaultColors.put("white", Color.rgb(255, 255, 255));
defaultColors.put("lime", Color.rgb(0, 255, 0));
defaultColors.put("cyan", Color.rgb(0, 255, 255));
defaultColors.put("red", Color.rgb(255, 0, 0));
defaultColors.put("yellow", Color.rgb(255, 255, 0));
defaultColors.put("magenta", Color.rgb(255, 0, 255));
defaultColors.put("blue", Color.rgb(0, 0, 255));
defaultColors.put("black", Color.rgb(0, 0, 0));
DEFAULT_TEXT_COLORS = Collections.unmodifiableMap(defaultColors);
}
/**
* See WebVTT's <a href="https://www.w3.org/TR/webvtt1/#default-text-background">default text
* background colors</a>.
*/
private static final Map<String, Integer> DEFAULT_BACKGROUND_COLORS;
static {
Map<String, Integer> defaultBackgroundColors = new HashMap<>();
defaultBackgroundColors.put("bg_white", Color.rgb(255, 255, 255));
defaultBackgroundColors.put("bg_lime", Color.rgb(0, 255, 0));
defaultBackgroundColors.put("bg_cyan", Color.rgb(0, 255, 255));
defaultBackgroundColors.put("bg_red", Color.rgb(255, 0, 0));
defaultBackgroundColors.put("bg_yellow", Color.rgb(255, 255, 0));
defaultBackgroundColors.put("bg_magenta", Color.rgb(255, 0, 255));
defaultBackgroundColors.put("bg_blue", Color.rgb(0, 0, 255));
defaultBackgroundColors.put("bg_black", Color.rgb(0, 0, 0));
DEFAULT_BACKGROUND_COLORS = Collections.unmodifiableMap(defaultBackgroundColors);
}
/**
* Parses the next valid WebVTT cue in a parsable array, including timestamps, settings and text.
*
@ -514,6 +555,8 @@ public final class WebvttCueParser {
text.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
case TAG_CLASS:
applyDefaultColors(text, startTag.classes, start, end);
break;
case TAG_LANG:
case TAG_VOICE:
case "": // Case of the "whole cue" virtual tag.
@ -529,6 +572,26 @@ public final class WebvttCueParser {
}
}
/**
* Adds {@link ForegroundColorSpan}s and {@link BackgroundColorSpan}s to {@code text} for entries
* in {@code classes} that match WebVTT's <a
* href="https://www.w3.org/TR/webvtt1/#default-text-color">default text colors</a> or <a
* href="https://www.w3.org/TR/webvtt1/#default-text-background">default text background
* colors</a>.
*/
private static void applyDefaultColors(
SpannableStringBuilder text, String[] classes, int start, int end) {
for (String className : classes) {
if (DEFAULT_TEXT_COLORS.containsKey(className)) {
int color = DEFAULT_TEXT_COLORS.get(className);
text.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (DEFAULT_BACKGROUND_COLORS.containsKey(className)) {
int color = DEFAULT_BACKGROUND_COLORS.get(className);
text.setSpan(new BackgroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private static void applyStyleToText(SpannableStringBuilder spannedText, WebvttCssStyle style,
int start, int end) {
if (style == null) {

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.text.webvtt;
import static com.google.android.exoplayer2.testutil.truth.SpannedSubject.assertThat;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Color;
import android.text.Spanned;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.text.span.RubySpan;
@ -79,6 +80,47 @@ public final class WebvttCueParserTest {
.withTextAndPosition("", RubySpan.POSITION_OVER);
}
@Test
public void testParseDefaultTextColor() throws Exception {
Spanned text = parseCueText("In this sentence <c.red>this text</c> is red");
assertThat(text.toString()).isEqualTo("In this sentence this text is red");
assertThat(text)
.hasForegroundColorSpanBetween(
"In this sentence ".length(), "In this sentence this text".length())
.withColor(Color.RED);
}
@Test
public void testParseUnsupportedDefaultTextColor() throws Exception {
Spanned text = parseCueText("In this sentence <c.papayawhip>this text</c> is not papaya");
assertThat(text.toString()).isEqualTo("In this sentence this text is not papaya");
assertThat(text).hasNoSpans();
}
@Test
public void testParseDefaultBackgroundColor() throws Exception {
Spanned text = parseCueText("In this sentence <c.bg_cyan>this text</c> has a cyan background");
assertThat(text.toString()).isEqualTo("In this sentence this text has a cyan background");
assertThat(text)
.hasBackgroundColorSpanBetween(
"In this sentence ".length(), "In this sentence this text".length())
.withColor(Color.CYAN);
}
@Test
public void testParseUnsupportedDefaultBackgroundColor() throws Exception {
Spanned text =
parseCueText(
"In this sentence <c.bg_papayawhip>this text</c> doesn't have a papaya background");
assertThat(text.toString())
.isEqualTo("In this sentence this text doesn't have a papaya background");
assertThat(text).hasNoSpans();
}
@Test
public void testParseWellFormedUnclosedEndAtCueEnd() throws Exception {
Spanned text = parseCueText("An <u some trailing stuff>unclosed u tag with "