Add cue positioning to SubtitleWebView

PiperOrigin-RevId: 303998690
This commit is contained in:
ibaker 2020-03-31 18:46:51 +01:00 committed by Oliver Woodman
parent 78c103e7ea
commit 802d71a5cb

View File

@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.ui.SubtitleView.DEFAULT_TEXT_SIZE_FR
import android.content.Context;
import android.graphics.Color;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
@ -28,6 +29,7 @@ import android.webkit.WebView;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.text.CaptionStyleCompat;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.util.Util;
import java.util.Collections;
import java.util.List;
@ -148,18 +150,116 @@ import java.util.List;
}
private void updateWebView() {
StringBuilder cueText = new StringBuilder();
StringBuilder html = new StringBuilder();
html.append("<html><body>")
.append("<div style=\"")
.append("-webkit-user-select:none;")
.append("position:fixed;")
.append("top:0;")
.append("bottom:0;")
.append("left:0;")
.append("right:0;")
.append("font-size:20px;")
.append("color:red;")
.append("\">");
for (int i = 0; i < cues.size(); i++) {
if (i > 0) {
cueText.append("<br>");
float horizontalPositionPercent;
int horizontalTranslatePercent;
Cue cue = cues.get(i);
if (cue.position != Cue.DIMEN_UNSET) {
horizontalPositionPercent = cue.position * 100;
horizontalTranslatePercent = translatePercentFromAnchorType(cue.positionAnchor);
} else {
horizontalPositionPercent = 50;
horizontalTranslatePercent = -50;
}
cueText.append(SpannedToHtmlConverter.convert(cues.get(i).text));
float verticalPositionPercent;
int verticalTranslatePercent;
if (cue.line != Cue.DIMEN_UNSET) {
verticalTranslatePercent = translatePercentFromAnchorType(cue.lineAnchor);
switch (cue.lineType) {
case Cue.LINE_TYPE_FRACTION:
verticalPositionPercent = cue.line * 100;
break;
case Cue.LINE_TYPE_NUMBER:
if (cue.line >= 0) {
verticalPositionPercent = 0;
verticalTranslatePercent += Math.round(cue.line) * 100;
} else {
verticalPositionPercent = 100;
verticalTranslatePercent += Math.round(cue.line + 1) * 100;
}
break;
case Cue.TYPE_UNSET:
default:
verticalPositionPercent = 0;
break;
}
} else {
verticalPositionPercent = 100;
verticalTranslatePercent = -100;
}
String width =
cue.size != Cue.DIMEN_UNSET
? Util.formatInvariant("%.2f%%", cue.size * 100)
: "fit-content";
String textAlign = convertAlignmentToCss(cue.textAlignment);
html.append(
Util.formatInvariant(
"<div style=\""
+ "position:relative;"
+ "left:%.2f%%;"
+ "top:%.2f%%;"
+ "width:%s;"
+ "text-align:%s;"
+ "transform:translate(%s%%,%s%%);"
+ "\">",
horizontalPositionPercent,
verticalPositionPercent,
width,
textAlign,
horizontalTranslatePercent,
verticalTranslatePercent))
.append(SpannedToHtmlConverter.convert(cue.text))
.append("</div>");
}
webView.loadData(
"<html><body><p style=\"color:red;font-size:20px;height:150px;-webkit-user-select:none;\">"
+ cueText
+ "</p></body></html>",
"text/html",
/* encoding= */ null);
html.append("</div></body></html>");
webView.loadData(html.toString(), "text/html", /* encoding= */ null);
}
private String convertAlignmentToCss(@Nullable Layout.Alignment alignment) {
if (alignment == null) {
return "unset";
}
switch (alignment) {
case ALIGN_NORMAL:
return "start";
case ALIGN_CENTER:
return "center";
case ALIGN_OPPOSITE:
return "end";
default:
return "unset";
}
}
private static int translatePercentFromAnchorType(@Cue.AnchorType int anchorType) {
switch (anchorType) {
case Cue.TYPE_UNSET:
case Cue.ANCHOR_TYPE_START:
return 0;
case Cue.ANCHOR_TYPE_MIDDLE:
return -50;
case Cue.ANCHOR_TYPE_END:
return -100;
}
throw new IllegalArgumentException();
}
}