mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Stop parsing unsupported WebVTT CSS properties
The spec lists an exhaustive list of CSS properties that should be recognised, all others must be ignored: https://www.w3.org/TR/webvtt1/#the-cue-pseudo-element PiperOrigin-RevId: 310353888
This commit is contained in:
parent
99ebeaed17
commit
252bf43bf4
7 changed files with 16 additions and 85 deletions
|
|
@ -116,6 +116,9 @@
|
||||||
horizontally.
|
horizontally.
|
||||||
* Implement steps 4-10 of the
|
* Implement steps 4-10 of the
|
||||||
[WebVTT line computation algorithm](https://www.w3.org/TR/webvtt1/#cue-computed-line).
|
[WebVTT line computation algorithm](https://www.w3.org/TR/webvtt1/#cue-computed-line).
|
||||||
|
* Stop parsing unsupported WebVTT CSS properties. The spec provides an
|
||||||
|
[exhaustive list](https://www.w3.org/TR/webvtt1/#the-cue-pseudo-element)
|
||||||
|
of which are supported.
|
||||||
* DRM:
|
* DRM:
|
||||||
* Add support for attaching DRM sessions to clear content in the demo app.
|
* Add support for attaching DRM sessions to clear content in the demo app.
|
||||||
* Remove `DrmSessionManager` references from all renderers.
|
* Remove `DrmSessionManager` references from all renderers.
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
private static final String RULE_START = "{";
|
private static final String RULE_START = "{";
|
||||||
private static final String RULE_END = "}";
|
private static final String RULE_END = "}";
|
||||||
private static final String PROPERTY_BGCOLOR = "background-color";
|
private static final String PROPERTY_COLOR = "color";
|
||||||
private static final String PROPERTY_FONT_FAMILY = "font-family";
|
private static final String PROPERTY_FONT_FAMILY = "font-family";
|
||||||
private static final String PROPERTY_FONT_WEIGHT = "font-weight";
|
private static final String PROPERTY_FONT_WEIGHT = "font-weight";
|
||||||
private static final String PROPERTY_TEXT_COMBINE_UPRIGHT = "text-combine-upright";
|
private static final String PROPERTY_TEXT_COMBINE_UPRIGHT = "text-combine-upright";
|
||||||
|
|
@ -184,10 +184,8 @@ import java.util.regex.Pattern;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// At this point we have a presumably valid declaration, we need to parse it and fill the style.
|
// At this point we have a presumably valid declaration, we need to parse it and fill the style.
|
||||||
if ("color".equals(property)) {
|
if (PROPERTY_COLOR.equals(property)) {
|
||||||
style.setFontColor(ColorParser.parseCssColor(value));
|
style.setFontColor(ColorParser.parseCssColor(value));
|
||||||
} else if (PROPERTY_BGCOLOR.equals(property)) {
|
|
||||||
style.setBackgroundColor(ColorParser.parseCssColor(value));
|
|
||||||
} else if (PROPERTY_TEXT_COMBINE_UPRIGHT.equals(property)) {
|
} else if (PROPERTY_TEXT_COMBINE_UPRIGHT.equals(property)) {
|
||||||
style.setCombineUpright(VALUE_ALL.equals(value) || value.startsWith(VALUE_DIGITS));
|
style.setCombineUpright(VALUE_ALL.equals(value) || value.startsWith(VALUE_DIGITS));
|
||||||
} else if (PROPERTY_TEXT_DECORATION.equals(property)) {
|
} else if (PROPERTY_TEXT_DECORATION.equals(property)) {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
package com.google.android.exoplayer2.text.webvtt;
|
package com.google.android.exoplayer2.text.webvtt;
|
||||||
|
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.text.Layout;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -86,15 +85,12 @@ public final class WebvttCssStyle {
|
||||||
@Nullable private String fontFamily;
|
@Nullable private String fontFamily;
|
||||||
private int fontColor;
|
private int fontColor;
|
||||||
private boolean hasFontColor;
|
private boolean hasFontColor;
|
||||||
private int backgroundColor;
|
|
||||||
private boolean hasBackgroundColor;
|
|
||||||
@OptionalBoolean private int linethrough;
|
@OptionalBoolean private int linethrough;
|
||||||
@OptionalBoolean private int underline;
|
@OptionalBoolean private int underline;
|
||||||
@OptionalBoolean private int bold;
|
@OptionalBoolean private int bold;
|
||||||
@OptionalBoolean private int italic;
|
@OptionalBoolean private int italic;
|
||||||
@FontSizeUnit private int fontSizeUnit;
|
@FontSizeUnit private int fontSizeUnit;
|
||||||
private float fontSize;
|
private float fontSize;
|
||||||
@Nullable private Layout.Alignment textAlign;
|
|
||||||
private boolean combineUpright;
|
private boolean combineUpright;
|
||||||
|
|
||||||
// Calling reset() is forbidden because `this` isn't initialized. This can be safely suppressed
|
// Calling reset() is forbidden because `this` isn't initialized. This can be safely suppressed
|
||||||
|
|
@ -112,13 +108,11 @@ public final class WebvttCssStyle {
|
||||||
targetVoice = "";
|
targetVoice = "";
|
||||||
fontFamily = null;
|
fontFamily = null;
|
||||||
hasFontColor = false;
|
hasFontColor = false;
|
||||||
hasBackgroundColor = false;
|
|
||||||
linethrough = UNSPECIFIED;
|
linethrough = UNSPECIFIED;
|
||||||
underline = UNSPECIFIED;
|
underline = UNSPECIFIED;
|
||||||
bold = UNSPECIFIED;
|
bold = UNSPECIFIED;
|
||||||
italic = UNSPECIFIED;
|
italic = UNSPECIFIED;
|
||||||
fontSizeUnit = UNSPECIFIED;
|
fontSizeUnit = UNSPECIFIED;
|
||||||
textAlign = null;
|
|
||||||
combineUpright = false;
|
combineUpright = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,33 +238,6 @@ public final class WebvttCssStyle {
|
||||||
return hasFontColor;
|
return hasFontColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBackgroundColor() {
|
|
||||||
if (!hasBackgroundColor) {
|
|
||||||
throw new IllegalStateException("Background color not defined.");
|
|
||||||
}
|
|
||||||
return backgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebvttCssStyle setBackgroundColor(int backgroundColor) {
|
|
||||||
this.backgroundColor = backgroundColor;
|
|
||||||
hasBackgroundColor = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasBackgroundColor() {
|
|
||||||
return hasBackgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Layout.Alignment getTextAlign() {
|
|
||||||
return textAlign;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebvttCssStyle setTextAlign(@Nullable Layout.Alignment textAlign) {
|
|
||||||
this.textAlign = textAlign;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebvttCssStyle setFontSize(float fontSize) {
|
public WebvttCssStyle setFontSize(float fontSize) {
|
||||||
this.fontSize = fontSize;
|
this.fontSize = fontSize;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import android.text.Spanned;
|
||||||
import android.text.SpannedString;
|
import android.text.SpannedString;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.style.AbsoluteSizeSpan;
|
import android.text.style.AbsoluteSizeSpan;
|
||||||
import android.text.style.AlignmentSpan;
|
|
||||||
import android.text.style.BackgroundColorSpan;
|
import android.text.style.BackgroundColorSpan;
|
||||||
import android.text.style.ForegroundColorSpan;
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.text.style.RelativeSizeSpan;
|
import android.text.style.RelativeSizeSpan;
|
||||||
|
|
@ -647,14 +646,6 @@ public final class WebvttCueParser {
|
||||||
end,
|
end,
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
if (style.hasBackgroundColor()) {
|
|
||||||
addOrReplaceSpan(
|
|
||||||
spannedText,
|
|
||||||
new BackgroundColorSpan(style.getBackgroundColor()),
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
}
|
|
||||||
if (style.getFontFamily() != null) {
|
if (style.getFontFamily() != null) {
|
||||||
addOrReplaceSpan(
|
addOrReplaceSpan(
|
||||||
spannedText,
|
spannedText,
|
||||||
|
|
@ -663,15 +654,6 @@ public final class WebvttCueParser {
|
||||||
end,
|
end,
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
Layout.Alignment textAlign = style.getTextAlign();
|
|
||||||
if (textAlign != null) {
|
|
||||||
addOrReplaceSpan(
|
|
||||||
spannedText,
|
|
||||||
new AlignmentSpan.Standard(textAlign),
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
}
|
|
||||||
switch (style.getFontSizeUnit()) {
|
switch (style.getFontSizeUnit()) {
|
||||||
case WebvttCssStyle.FONT_SIZE_UNIT_PIXEL:
|
case WebvttCssStyle.FONT_SIZE_UNIT_PIXEL:
|
||||||
addOrReplaceSpan(
|
addOrReplaceSpan(
|
||||||
|
|
|
||||||
|
|
@ -89,41 +89,33 @@ public final class CssParserTest {
|
||||||
@Test
|
@Test
|
||||||
public void parseMethodSimpleInput() {
|
public void parseMethodSimpleInput() {
|
||||||
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
||||||
String styleBlock1 = " ::cue { color : black; background-color: PapayaWhip }";
|
String styleBlock1 = " ::cue { color : PapayaWhip }";
|
||||||
expectedStyle.setFontColor(0xFF000000);
|
expectedStyle.setFontColor(0xFFFFEFD5);
|
||||||
expectedStyle.setBackgroundColor(0xFFFFEFD5);
|
|
||||||
assertParserProduces(styleBlock1, expectedStyle);
|
assertParserProduces(styleBlock1, expectedStyle);
|
||||||
|
|
||||||
String styleBlock2 = " ::cue { color : black }\n\n::cue { color : invalid }";
|
String styleBlock2 = " ::cue { color : black }\n\n::cue { color : invalid }";
|
||||||
expectedStyle = new WebvttCssStyle();
|
expectedStyle = new WebvttCssStyle();
|
||||||
expectedStyle.setFontColor(0xFF000000);
|
expectedStyle.setFontColor(0xFF000000);
|
||||||
assertParserProduces(styleBlock2, expectedStyle);
|
assertParserProduces(styleBlock2, expectedStyle);
|
||||||
|
|
||||||
String styleBlock3 = "::cue {\n background-color\n:#00fFFe}";
|
|
||||||
expectedStyle = new WebvttCssStyle();
|
|
||||||
expectedStyle.setBackgroundColor(0xFF00FFFE);
|
|
||||||
assertParserProduces(styleBlock3, expectedStyle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseMethodMultipleRulesInBlockInput() {
|
public void parseMethodMultipleRulesInBlockInput() {
|
||||||
String styleBlock =
|
String styleBlock = "::cue {\n color\n:#00fFFe} \n::cue {\n color\n:#00000000}\n";
|
||||||
"::cue {\n background-color\n:#00fFFe} \n::cue {\n background-color\n:#00000000}\n";
|
|
||||||
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
||||||
expectedStyle.setBackgroundColor(0xFF00FFFE);
|
expectedStyle.setFontColor(0xFF00FFFE);
|
||||||
WebvttCssStyle secondExpectedStyle = new WebvttCssStyle();
|
WebvttCssStyle secondExpectedStyle = new WebvttCssStyle();
|
||||||
secondExpectedStyle.setBackgroundColor(0x000000);
|
secondExpectedStyle.setFontColor(0x000000);
|
||||||
assertParserProduces(styleBlock, expectedStyle, secondExpectedStyle);
|
assertParserProduces(styleBlock, expectedStyle, secondExpectedStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multiplePropertiesInBlock() {
|
public void multiplePropertiesInBlock() {
|
||||||
String styleBlock = "::cue(#id){text-decoration:underline; background-color:green;"
|
String styleBlock =
|
||||||
+ "color:red; font-family:Courier; font-weight:bold}";
|
"::cue(#id){text-decoration:underline; color:red; font-family:Courier; font-weight:bold}";
|
||||||
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
||||||
expectedStyle.setTargetId("id");
|
expectedStyle.setTargetId("id");
|
||||||
expectedStyle.setUnderline(true);
|
expectedStyle.setUnderline(true);
|
||||||
expectedStyle.setBackgroundColor(0xFF008000);
|
|
||||||
expectedStyle.setFontColor(0xFFFF0000);
|
expectedStyle.setFontColor(0xFFFF0000);
|
||||||
expectedStyle.setFontFamily("courier");
|
expectedStyle.setFontFamily("courier");
|
||||||
expectedStyle.setBold(true);
|
expectedStyle.setBold(true);
|
||||||
|
|
@ -133,12 +125,10 @@ public final class CssParserTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rgbaColorExpression() {
|
public void rgbaColorExpression() {
|
||||||
String styleBlock = "::cue(#rgb){background-color: rgba(\n10/* Ugly color */,11\t, 12\n,.1);"
|
String styleBlock = "::cue(#rgb){color: rgba(\n10/* Ugly color */,11\t, 12\n,.1);}";
|
||||||
+ "color:rgb(1,1,\n1)}";
|
|
||||||
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
WebvttCssStyle expectedStyle = new WebvttCssStyle();
|
||||||
expectedStyle.setTargetId("rgb");
|
expectedStyle.setTargetId("rgb");
|
||||||
expectedStyle.setBackgroundColor(0x190A0B0C);
|
expectedStyle.setFontColor(0x190A0B0C);
|
||||||
expectedStyle.setFontColor(0xFF010101);
|
|
||||||
|
|
||||||
assertParserProduces(styleBlock, expectedStyle);
|
assertParserProduces(styleBlock, expectedStyle);
|
||||||
}
|
}
|
||||||
|
|
@ -222,10 +212,6 @@ public final class CssParserTest {
|
||||||
for (int i = 0; i < expectedStyles.length; i++) {
|
for (int i = 0; i < expectedStyles.length; i++) {
|
||||||
WebvttCssStyle expected = expectedStyles[i];
|
WebvttCssStyle expected = expectedStyles[i];
|
||||||
WebvttCssStyle actualElem = styles.get(i);
|
WebvttCssStyle actualElem = styles.get(i);
|
||||||
assertThat(actualElem.hasBackgroundColor()).isEqualTo(expected.hasBackgroundColor());
|
|
||||||
if (expected.hasBackgroundColor()) {
|
|
||||||
assertThat(actualElem.getBackgroundColor()).isEqualTo(expected.getBackgroundColor());
|
|
||||||
}
|
|
||||||
assertThat(actualElem.hasFontColor()).isEqualTo(expected.hasFontColor());
|
assertThat(actualElem.hasFontColor()).isEqualTo(expected.hasFontColor());
|
||||||
if (expected.hasFontColor()) {
|
if (expected.hasFontColor()) {
|
||||||
assertThat(actualElem.getFontColor()).isEqualTo(expected.getFontColor());
|
assertThat(actualElem.getFontColor()).isEqualTo(expected.getFontColor());
|
||||||
|
|
@ -236,7 +222,6 @@ public final class CssParserTest {
|
||||||
assertThat(actualElem.getStyle()).isEqualTo(expected.getStyle());
|
assertThat(actualElem.getStyle()).isEqualTo(expected.getStyle());
|
||||||
assertThat(actualElem.isLinethrough()).isEqualTo(expected.isLinethrough());
|
assertThat(actualElem.isLinethrough()).isEqualTo(expected.isLinethrough());
|
||||||
assertThat(actualElem.isUnderline()).isEqualTo(expected.isUnderline());
|
assertThat(actualElem.isUnderline()).isEqualTo(expected.isUnderline());
|
||||||
assertThat(actualElem.getTextAlign()).isEqualTo(expected.getTextAlign());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -371,9 +371,6 @@ public class WebvttDecoderTest {
|
||||||
assertThat(firstCueText)
|
assertThat(firstCueText)
|
||||||
.hasForegroundColorSpanBetween(0, firstCueText.length())
|
.hasForegroundColorSpanBetween(0, firstCueText.length())
|
||||||
.withColor(ColorParser.parseCssColor("papayawhip"));
|
.withColor(ColorParser.parseCssColor("papayawhip"));
|
||||||
assertThat(firstCueText)
|
|
||||||
.hasBackgroundColorSpanBetween(0, firstCueText.length())
|
|
||||||
.withColor(ColorParser.parseCssColor("green"));
|
|
||||||
|
|
||||||
Spanned secondCueText = getUniqueSpanTextAt(subtitle, 2_345_000);
|
Spanned secondCueText = getUniqueSpanTextAt(subtitle, 2_345_000);
|
||||||
assertThat(secondCueText.toString()).isEqualTo("This is the second subtitle.");
|
assertThat(secondCueText.toString()).isEqualTo("This is the second subtitle.");
|
||||||
|
|
@ -388,7 +385,7 @@ public class WebvttDecoderTest {
|
||||||
Spanned fourthCueText = getUniqueSpanTextAt(subtitle, 25_000_000);
|
Spanned fourthCueText = getUniqueSpanTextAt(subtitle, 25_000_000);
|
||||||
assertThat(fourthCueText.toString()).isEqualTo("You are an idiot\nYou don't have the guts");
|
assertThat(fourthCueText.toString()).isEqualTo("You are an idiot\nYou don't have the guts");
|
||||||
assertThat(fourthCueText)
|
assertThat(fourthCueText)
|
||||||
.hasBackgroundColorSpanBetween(0, "You are an idiot".length())
|
.hasForegroundColorSpanBetween(0, "You are an idiot".length())
|
||||||
.withColor(ColorParser.parseCssColor("lime"));
|
.withColor(ColorParser.parseCssColor("lime"));
|
||||||
assertThat(fourthCueText)
|
assertThat(fourthCueText)
|
||||||
.hasBoldSpanBetween("You are an idiot\n".length(), fourthCueText.length());
|
.hasBoldSpanBetween("You are an idiot\n".length(), fourthCueText.length());
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ WEBVTT
|
||||||
|
|
||||||
STYLE
|
STYLE
|
||||||
::cue {
|
::cue {
|
||||||
background-color: green;
|
|
||||||
color: papayawhip;
|
color: papayawhip;
|
||||||
}
|
}
|
||||||
/* Style blocks cannot use blank lines nor "dash dash greater than" */
|
/* Style blocks cannot use blank lines nor "dash dash greater than" */
|
||||||
|
|
@ -13,7 +12,7 @@ STYLE
|
||||||
::cue(#id2) {
|
::cue(#id2) {
|
||||||
color: peachpuff;
|
color: peachpuff;
|
||||||
}
|
}
|
||||||
::cue(v[voice="LaGord"]) { background-color: lime }
|
::cue(v[voice="LaGord"]) { color: lime }
|
||||||
|
|
||||||
STYLE
|
STYLE
|
||||||
::cue(v[voice="The Frog"]) { font-weight: bold }
|
::cue(v[voice="The Frog"]) { font-weight: bold }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue