use of com.google.android.exoplayer2.text.Cue in project ExoPlayer by google.
the class DefaultAnalyticsCollector method onCues.
@Override
public void onCues(List<Cue> cues) {
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
sendEvent(eventTime, AnalyticsListener.EVENT_CUES, listener -> listener.onCues(eventTime, cues));
}
use of com.google.android.exoplayer2.text.Cue in project ExoPlayer by google.
the class ImaAdsLoaderTest method loadAd_withLargeAdCuePoint_updatesAdPlaybackStateWithLoadedAd.
@Test
public void loadAd_withLargeAdCuePoint_updatesAdPlaybackStateWithLoadedAd() {
// Use a large enough value to test correct truncating of large cue points.
float midrollTimeSecs = Float.MAX_VALUE;
List<Float> cuePoints = ImmutableList.of(midrollTimeSecs);
when(mockAdsManager.getAdCuePoints()).thenReturn(cuePoints);
imaAdsLoader.start(adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
videoAdPlayer.loadAd(TEST_AD_MEDIA_INFO, new AdPodInfo() {
@Override
public int getTotalAds() {
return 1;
}
@Override
public int getAdPosition() {
return 1;
}
@Override
public boolean isBumper() {
return false;
}
@Override
public double getMaxDuration() {
return 0;
}
@Override
public int getPodIndex() {
return 0;
}
@Override
public double getTimeOffset() {
return midrollTimeSecs;
}
});
assertThat(getAdPlaybackState(/* periodIndex= */
0)).isEqualTo(new AdPlaybackState(TEST_ADS_ID, getAdGroupTimesUsForCuePoints(cuePoints)).withContentDurationUs(CONTENT_PERIOD_DURATION_US).withAdCount(/* adGroupIndex= */
0, /* adCount= */
1).withAdUri(/* adGroupIndex= */
0, /* adIndexInAdGroup= */
0, TEST_URI).withAdDurationsUs(new long[][] { { TEST_AD_DURATION_US } }));
}
use of com.google.android.exoplayer2.text.Cue in project ExoPlayer by google.
the class Cea608Decoder method getDisplayCues.
private List<Cue> getDisplayCues() {
// CEA-608 does not define middle and end alignment, however content providers artificially
// introduce them using whitespace. When each cue is built, we try and infer the alignment based
// on the amount of whitespace either side of the text. To avoid consecutive cues being aligned
// differently, we force all cues to have the same alignment, with start alignment given
// preference, then middle alignment, then end alignment.
@Cue.AnchorType int positionAnchor = Cue.ANCHOR_TYPE_END;
int cueBuilderCount = cueBuilders.size();
List<@NullableType Cue> cueBuilderCues = new ArrayList<>(cueBuilderCount);
for (int i = 0; i < cueBuilderCount; i++) {
@Nullable Cue cue = cueBuilders.get(i).build(/* forcedPositionAnchor= */
Cue.TYPE_UNSET);
cueBuilderCues.add(cue);
if (cue != null) {
positionAnchor = min(positionAnchor, cue.positionAnchor);
}
}
// Skip null cues and rebuild any that don't have the preferred alignment.
List<Cue> displayCues = new ArrayList<>(cueBuilderCount);
for (int i = 0; i < cueBuilderCount; i++) {
@Nullable Cue cue = cueBuilderCues.get(i);
if (cue != null) {
if (cue.positionAnchor != positionAnchor) {
// The last time we built this cue it was non-null, it will be non-null this time too.
cue = Assertions.checkNotNull(cueBuilders.get(i).build(positionAnchor));
}
displayCues.add(cue);
}
}
return displayCues;
}
use of com.google.android.exoplayer2.text.Cue in project ExoPlayer by google.
the class WebViewSubtitleOutput method updateWebView.
private void updateWebView() {
StringBuilder html = new StringBuilder();
html.append(Util.formatInvariant("<body><div style='" + "-webkit-user-select:none;" + "position:fixed;" + "top:0;" + "bottom:0;" + "left:0;" + "right:0;" + "color:%s;" + "font-size:%s;" + "line-height:%.2f;" + "text-shadow:%s;" + "'>", HtmlUtils.toCssRgba(style.foregroundColor), convertTextSizeToCss(defaultTextSizeType, defaultTextSize), CSS_LINE_HEIGHT, convertCaptionStyleToCssTextShadow(style)));
Map<String, String> cssRuleSets = new HashMap<>();
cssRuleSets.put(HtmlUtils.cssAllClassDescendantsSelector(DEFAULT_BACKGROUND_CSS_CLASS), Util.formatInvariant("background-color:%s;", HtmlUtils.toCssRgba(style.backgroundColor)));
for (int i = 0; i < textCues.size(); i++) {
Cue cue = textCues.get(i);
float positionPercent = (cue.position != Cue.DIMEN_UNSET) ? (cue.position * 100) : 50;
int positionAnchorTranslatePercent = anchorTypeToTranslatePercent(cue.positionAnchor);
String lineValue;
boolean lineMeasuredFromEnd = false;
int lineAnchorTranslatePercent = 0;
if (cue.line != Cue.DIMEN_UNSET) {
switch(cue.lineType) {
case Cue.LINE_TYPE_NUMBER:
if (cue.line >= 0) {
lineValue = Util.formatInvariant("%.2fem", cue.line * CSS_LINE_HEIGHT);
} else {
lineValue = Util.formatInvariant("%.2fem", (-cue.line - 1) * CSS_LINE_HEIGHT);
lineMeasuredFromEnd = true;
}
break;
case Cue.LINE_TYPE_FRACTION:
case Cue.TYPE_UNSET:
default:
lineValue = Util.formatInvariant("%.2f%%", cue.line * 100);
lineAnchorTranslatePercent = cue.verticalType == Cue.VERTICAL_TYPE_RL ? -anchorTypeToTranslatePercent(cue.lineAnchor) : anchorTypeToTranslatePercent(cue.lineAnchor);
}
} else {
lineValue = Util.formatInvariant("%.2f%%", (1.0f - bottomPaddingFraction) * 100);
lineAnchorTranslatePercent = -100;
}
String size = cue.size != Cue.DIMEN_UNSET ? Util.formatInvariant("%.2f%%", cue.size * 100) : "fit-content";
String textAlign = convertAlignmentToCss(cue.textAlignment);
String writingMode = convertVerticalTypeToCss(cue.verticalType);
String cueTextSizeCssPx = convertTextSizeToCss(cue.textSizeType, cue.textSize);
String windowCssColor = HtmlUtils.toCssRgba(cue.windowColorSet ? cue.windowColor : style.windowColor);
String positionProperty;
String lineProperty;
switch(cue.verticalType) {
case Cue.VERTICAL_TYPE_LR:
lineProperty = lineMeasuredFromEnd ? "right" : "left";
positionProperty = "top";
break;
case Cue.VERTICAL_TYPE_RL:
lineProperty = lineMeasuredFromEnd ? "left" : "right";
positionProperty = "top";
break;
case Cue.TYPE_UNSET:
default:
lineProperty = lineMeasuredFromEnd ? "bottom" : "top";
positionProperty = "left";
}
String sizeProperty;
int horizontalTranslatePercent;
int verticalTranslatePercent;
if (cue.verticalType == Cue.VERTICAL_TYPE_LR || cue.verticalType == Cue.VERTICAL_TYPE_RL) {
sizeProperty = "height";
horizontalTranslatePercent = lineAnchorTranslatePercent;
verticalTranslatePercent = positionAnchorTranslatePercent;
} else {
sizeProperty = "width";
horizontalTranslatePercent = positionAnchorTranslatePercent;
verticalTranslatePercent = lineAnchorTranslatePercent;
}
SpannedToHtmlConverter.HtmlAndCss htmlAndCss = SpannedToHtmlConverter.convert(cue.text, getContext().getResources().getDisplayMetrics().density);
for (String cssSelector : cssRuleSets.keySet()) {
@Nullable String previousCssDeclarationBlock = cssRuleSets.put(cssSelector, cssRuleSets.get(cssSelector));
Assertions.checkState(previousCssDeclarationBlock == null || previousCssDeclarationBlock.equals(cssRuleSets.get(cssSelector)));
}
html.append(Util.formatInvariant("<div style='" + "position:absolute;" + "z-index:%s;" + "%s:%.2f%%;" + "%s:%s;" + "%s:%s;" + "text-align:%s;" + "writing-mode:%s;" + "font-size:%s;" + "background-color:%s;" + "transform:translate(%s%%,%s%%)" + "%s;" + "'>", /* z-index */
i, positionProperty, positionPercent, lineProperty, lineValue, sizeProperty, size, textAlign, writingMode, cueTextSizeCssPx, windowCssColor, horizontalTranslatePercent, verticalTranslatePercent, getBlockShearTransformFunction(cue))).append(Util.formatInvariant("<span class='%s'>", DEFAULT_BACKGROUND_CSS_CLASS));
if (cue.multiRowAlignment != null) {
html.append(Util.formatInvariant("<span style='display:inline-block; text-align:%s;'>", convertAlignmentToCss(cue.multiRowAlignment))).append(htmlAndCss.html).append("</span>");
} else {
html.append(htmlAndCss.html);
}
html.append("</span>").append("</div>");
}
html.append("</div></body></html>");
StringBuilder htmlHead = new StringBuilder();
htmlHead.append("<html><head><style>");
for (String cssSelector : cssRuleSets.keySet()) {
htmlHead.append(cssSelector).append("{").append(cssRuleSets.get(cssSelector)).append("}");
}
htmlHead.append("</style></head>");
html.insert(0, htmlHead.toString());
webView.loadData(Base64.encodeToString(html.toString().getBytes(Charsets.UTF_8), Base64.NO_PADDING), "text/html", "base64");
}
use of com.google.android.exoplayer2.text.Cue in project ExoPlayer by google.
the class SubtitleViewUtilsTest method buildCue.
private static Cue buildCue() {
SpannableString spanned = new SpannableString("TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize");
spanned.setSpan(new TextEmphasisSpan(TextEmphasisSpan.MARK_SHAPE_CIRCLE, TextEmphasisSpan.MARK_FILL_FILLED, TextAnnotation.POSITION_BEFORE), "Text emphasis ".length(), "Text emphasis おはよ".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new RubySpan("おはよ", TextAnnotation.POSITION_BEFORE), "TextEmphasis おはよ Ruby ".length(), "TextEmphasis おはよ Ruby ございます".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new HorizontalTextInVerticalContextSpan(), "TextEmphasis おはよ Ruby ございます ".length(), "TextEmphasis おはよ Ruby ございます 123".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new UnderlineSpan(), "TextEmphasis おはよ Ruby ございます 123 ".length(), "TextEmphasis おはよ Ruby ございます 123 Underline".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new RelativeSizeSpan(1f), "TextEmphasis おはよ Ruby ございます 123 Underline ".length(), "TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new AbsoluteSizeSpan(10), "TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize ".length(), "TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return new Cue.Builder().setText(spanned).setTextAlignment(Layout.Alignment.ALIGN_CENTER).setMultiRowAlignment(Layout.Alignment.ALIGN_NORMAL).setLine(5, Cue.LINE_TYPE_NUMBER).setLineAnchor(Cue.ANCHOR_TYPE_END).setPosition(0.4f).setPositionAnchor(Cue.ANCHOR_TYPE_MIDDLE).setTextSize(0.2f, Cue.TEXT_SIZE_TYPE_FRACTIONAL).setSize(0.8f).setWindowColor(Color.CYAN).setVerticalType(Cue.VERTICAL_TYPE_RL).setShearDegrees(-15f).build();
}
Aggregations