mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add cue positioning to SubtitleWebView
PiperOrigin-RevId: 303998690
This commit is contained in:
parent
78c103e7ea
commit
802d71a5cb
@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.ui.SubtitleView.DEFAULT_TEXT_SIZE_FR
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.text.Layout;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -28,6 +29,7 @@ import android.webkit.WebView;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.text.CaptionStyleCompat;
|
import com.google.android.exoplayer2.text.CaptionStyleCompat;
|
||||||
import com.google.android.exoplayer2.text.Cue;
|
import com.google.android.exoplayer2.text.Cue;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -148,18 +150,116 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateWebView() {
|
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++) {
|
for (int i = 0; i < cues.size(); i++) {
|
||||||
if (i > 0) {
|
float horizontalPositionPercent;
|
||||||
cueText.append("<br>");
|
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;
|
||||||
}
|
}
|
||||||
webView.loadData(
|
break;
|
||||||
"<html><body><p style=\"color:red;font-size:20px;height:150px;-webkit-user-select:none;\">"
|
case Cue.TYPE_UNSET:
|
||||||
+ cueText
|
default:
|
||||||
+ "</p></body></html>",
|
verticalPositionPercent = 0;
|
||||||
"text/html",
|
break;
|
||||||
/* encoding= */ null);
|
}
|
||||||
|
} 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>");
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user