java.lang.Object
↳androidx.media3.common.text.Cue
Gradle dependencies
compile group: 'androidx.media3', name: 'media3-common', version: '1.5.0-alpha01'
- groupId: androidx.media3
- artifactId: media3-common
- version: 1.5.0-alpha01
Artifact androidx.media3:media3-common:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)
Overview
Contains information about a specific cue, including textual content and formatting data.
Summary
Fields |
---|
public static final int | ANCHOR_TYPE_END Anchors the right (for horizontal positions) or bottom (for vertical positions) edge of the cue
box. |
public static final int | ANCHOR_TYPE_MIDDLE Anchors the middle of the cue box. |
public static final int | ANCHOR_TYPE_START Anchors the left (for horizontal positions) or top (for vertical positions) edge of the cue
box. |
public final Bitmap | bitmap The cue image, or null if this is a text cue. |
public final float | bitmapHeight The bitmap height as a fraction of the of the viewport size, or Cue.DIMEN_UNSET if the
bitmap should be displayed at its natural height given the bitmap dimensions and the specified
Cue.size. |
public static final float | DIMEN_UNSET An unset position, width or size. |
public static final Cue | EMPTY |
public final float | line The position of the cue box within the viewport in the direction orthogonal to the writing
direction (determined by Cue.verticalType), or Cue.DIMEN_UNSET. |
public static final int | LINE_TYPE_FRACTION Value for Cue.lineType when Cue.line is a fractional position. |
public static final int | LINE_TYPE_NUMBER Value for Cue.lineType when Cue.line is a line number. |
public final int | lineAnchor The cue box anchor positioned by Cue.line when Cue.lineType is Cue.LINE_TYPE_FRACTION. |
public final int | lineType The type of the Cue.line value. |
public final Alignment | multiRowAlignment The alignment of multiple lines of text relative to the longest line, or null if the alignment
is undefined. |
public final float | position The fractional position of the Cue.positionAnchor of the cue box within the viewport in
the direction orthogonal to Cue.line, or Cue.DIMEN_UNSET. |
public final int | positionAnchor The cue box anchor positioned by Cue.position. |
public final float | shearDegrees The shear angle in degrees to be applied to this Cue, expressed in graphics coordinates. |
public final float | size The size of the cue box in the writing direction specified as a fraction of the viewport size
in that direction, or Cue.DIMEN_UNSET. |
public final java.lang.CharSequence | text The cue text, or null if this is an image cue. |
public static final int | TEXT_SIZE_TYPE_ABSOLUTE Text size is measured in number of pixels. |
public static final int | TEXT_SIZE_TYPE_FRACTIONAL Text size is measured as a fraction of the viewport size minus the view padding. |
public static final int | TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING Text size is measured as a fraction of the viewport size, ignoring the view padding |
public final Alignment | textAlignment The alignment of the cue text within the cue box, or null if the alignment is undefined. |
public final float | textSize The default text size for this cue's text, or Cue.DIMEN_UNSET if this cue has no default
text size. |
public final int | textSizeType The default text size type for this cue's text, or Cue.TYPE_UNSET if this cue has no
default text size. |
public static final int | TYPE_UNSET An unset anchor, line, text size or vertical type value. |
public static final int | VERTICAL_TYPE_LR Vertical left-to-right (e.g. |
public static final int | VERTICAL_TYPE_RL Vertical right-to-left (e.g. |
public final int | verticalType The vertical formatting of this Cue, or Cue.TYPE_UNSET if the cue has no vertical setting
(and so should be horizontal). |
public final int | windowColor The fill color of the window. |
public final boolean | windowColorSet Specifies whether or not the Cue.windowColor property is set. |
Fields
public static final
Cue EMPTYDeprecated: There's no general need for a cue with an empty text string. If you need one,
create it yourself.
public static final float
DIMEN_UNSETAn unset position, width or size.
public static final int
TYPE_UNSETAn unset anchor, line, text size or vertical type value.
public static final int
ANCHOR_TYPE_STARTAnchors the left (for horizontal positions) or top (for vertical positions) edge of the cue
box.
public static final int
ANCHOR_TYPE_MIDDLEAnchors the middle of the cue box.
public static final int
ANCHOR_TYPE_ENDAnchors the right (for horizontal positions) or bottom (for vertical positions) edge of the cue
box.
public static final int
LINE_TYPE_FRACTIONValue for Cue.lineType when Cue.line is a fractional position.
public static final int
LINE_TYPE_NUMBERValue for Cue.lineType when Cue.line is a line number.
public static final int
TEXT_SIZE_TYPE_FRACTIONALText size is measured as a fraction of the viewport size minus the view padding.
public static final int
TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDINGText size is measured as a fraction of the viewport size, ignoring the view padding
public static final int
TEXT_SIZE_TYPE_ABSOLUTEText size is measured in number of pixels.
public static final int
VERTICAL_TYPE_RLVertical right-to-left (e.g. for Japanese).
public static final int
VERTICAL_TYPE_LRVertical left-to-right (e.g. for Mongolian).
public final java.lang.CharSequence
textThe cue text, or null if this is an image cue. Note the java.lang.CharSequence
may be decorated
with styling spans.
public final Alignment
textAlignmentThe alignment of the cue text within the cue box, or null if the alignment is undefined.
public final Alignment
multiRowAlignmentThe alignment of multiple lines of text relative to the longest line, or null if the alignment
is undefined.
public final Bitmap
bitmapThe cue image, or null if this is a text cue.
The position of the cue box within the viewport in the direction orthogonal to the writing
direction (determined by Cue.verticalType), or Cue.DIMEN_UNSET. When set, the
interpretation of the value depends on the value of Cue.lineType.
The measurement direction depends on Cue.verticalType:
- For Cue.TYPE_UNSET (i.e. horizontal), this is the vertical position relative to the
top of the viewport.
- For Cue.VERTICAL_TYPE_LR this is the horizontal position relative to the left of the
viewport.
- For Cue.VERTICAL_TYPE_RL this is the horizontal position relative to the right of
the viewport.
public final int
lineTypeThe type of the Cue.line value.
- Cue.LINE_TYPE_FRACTION indicates that Cue.line is a fractional position within
the viewport (measured to the part of the cue box determined by Cue.lineAnchor).
- Cue.LINE_TYPE_NUMBER indicates that Cue.line is a viewport line number. The
viewport is divided into lines (each equal in size to the first line of the cue box). The
cue box is positioned to align with the viewport lines as follows:
- Cue.lineAnchor) is ignored.
- When line is greater than or equal to 0 the first line in the cue box is
aligned with a viewport line, with 0 meaning the first line of the viewport.
- When line is negative the last line in the cue box is aligned with a
viewport line, with -1 meaning the last line of the viewport.
- For horizontal text the start and end of the viewport are the top and bottom
respectively.
public final int
lineAnchorThe cue box anchor positioned by Cue.line when Cue.lineType is Cue.LINE_TYPE_FRACTION.
One of:
For the normal case of horizontal text, Cue.ANCHOR_TYPE_START, Cue.ANCHOR_TYPE_MIDDLE and Cue.ANCHOR_TYPE_END correspond to the top, middle and bottom of
the cue box respectively.
public final float
positionThe fractional position of the Cue.positionAnchor of the cue box within the viewport in
the direction orthogonal to Cue.line, or Cue.DIMEN_UNSET.
The measurement direction depends on Cue.verticalType.
- For Cue.TYPE_UNSET (i.e. horizontal), this is the horizontal position relative to
the left of the viewport. Note that positioning is relative to the left of the viewport
even in the case of right-to-left text.
- For Cue.VERTICAL_TYPE_LR and Cue.VERTICAL_TYPE_RL (i.e. vertical), this is the
vertical position relative to the top of the viewport.
public final int
positionAnchorThe cue box anchor positioned by Cue.position. One of Cue.ANCHOR_TYPE_START, Cue.ANCHOR_TYPE_MIDDLE, Cue.ANCHOR_TYPE_END and Cue.TYPE_UNSET.
For the normal case of horizontal text, Cue.ANCHOR_TYPE_START, Cue.ANCHOR_TYPE_MIDDLE and Cue.ANCHOR_TYPE_END correspond to the left, middle and right of
the cue box respectively.
The size of the cue box in the writing direction specified as a fraction of the viewport size
in that direction, or Cue.DIMEN_UNSET.
public final float
bitmapHeightThe bitmap height as a fraction of the of the viewport size, or Cue.DIMEN_UNSET if the
bitmap should be displayed at its natural height given the bitmap dimensions and the specified
Cue.size.
public final boolean
windowColorSetSpecifies whether or not the Cue.windowColor property is set.
public final int
windowColorThe fill color of the window.
public final int
textSizeTypeThe default text size type for this cue's text, or Cue.TYPE_UNSET if this cue has no
default text size.
public final float
textSizeThe default text size for this cue's text, or Cue.DIMEN_UNSET if this cue has no default
text size.
public final int
verticalTypeThe vertical formatting of this Cue, or Cue.TYPE_UNSET if the cue has no vertical setting
(and so should be horizontal).
public final float
shearDegreesThe shear angle in degrees to be applied to this Cue, expressed in graphics coordinates. This
results in a skew transform for the block along the inline progression axis.
Methods
Returns a new Cue.Builder initialized with the same values as this Cue.
public boolean
equals(java.lang.Object obj)
public Bundle
toSerializableBundle()
Returns a that can be serialized to bytes.
Prefer the more efficient Cue.toBinderBasedBundle() if the result doesn't need to be
serialized.
The returned from this method must not be passed to other processes that
might be using a different version of the media3 library.
public Bundle
toBinderBasedBundle()
Returns a that may contain references, meaning it cannot be
safely serialized to bytes.
The returned from this method can be safely sent between processes and parsed
by older versions of the media3 library.
Use Cue.toSerializableBundle() to get a that can be safely serialized.
Deprecated: Use Cue.toSerializableBundle() or Cue.toBinderBasedBundle() instead.
public static
Cue fromBundle(Bundle bundle)
Restores a cue from a .
Source
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.common.text;
import static androidx.media3.common.text.CustomSpanBundler.bundleCustomSpans;
import static androidx.media3.common.util.Assertions.checkState;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Binder;
import android.os.Bundle;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.SpannedString;
import android.text.TextUtils;
import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.base.Objects;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.ByteArrayOutputStream;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import org.checkerframework.dataflow.qual.Pure;
/** Contains information about a specific cue, including textual content and formatting data. */
// This class shouldn't be sub-classed. If a subtitle format needs additional fields, either they
// should be generic enough to be added here, or the format-specific decoder should pass the
// information around in a sidecar object.
public final class Cue {
/**
* @deprecated There's no general need for a cue with an empty text string. If you need one,
* create it yourself.
*/
@Deprecated public static final Cue EMPTY = new Cue.Builder().setText("").build();
/** An unset position, width or size. */
// Note: We deliberately don't use Float.MIN_VALUE because it's positive & very close to zero.
public static final float DIMEN_UNSET = -Float.MAX_VALUE;
/**
* The type of anchor, which may be unset. One of {@link #TYPE_UNSET}, {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE} or {@link #ANCHOR_TYPE_END}.
*/
// @Target list includes both 'default' targets and TYPE_USE, to ensure backwards compatibility
// with Kotlin usages from before TYPE_USE was added.
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
@IntDef({TYPE_UNSET, ANCHOR_TYPE_START, ANCHOR_TYPE_MIDDLE, ANCHOR_TYPE_END})
public @interface AnchorType {}
/** An unset anchor, line, text size or vertical type value. */
public static final int TYPE_UNSET = Integer.MIN_VALUE;
/**
* Anchors the left (for horizontal positions) or top (for vertical positions) edge of the cue
* box.
*/
public static final int ANCHOR_TYPE_START = 0;
/** Anchors the middle of the cue box. */
public static final int ANCHOR_TYPE_MIDDLE = 1;
/**
* Anchors the right (for horizontal positions) or bottom (for vertical positions) edge of the cue
* box.
*/
public static final int ANCHOR_TYPE_END = 2;
/**
* The type of line, which may be unset. One of {@link #TYPE_UNSET}, {@link #LINE_TYPE_FRACTION}
* or {@link #LINE_TYPE_NUMBER}.
*/
// @Target list includes both 'default' targets and TYPE_USE, to ensure backwards compatibility
// with Kotlin usages from before TYPE_USE was added.
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
@IntDef({TYPE_UNSET, LINE_TYPE_FRACTION, LINE_TYPE_NUMBER})
public @interface LineType {}
/** Value for {@link #lineType} when {@link #line} is a fractional position. */
public static final int LINE_TYPE_FRACTION = 0;
/** Value for {@link #lineType} when {@link #line} is a line number. */
public static final int LINE_TYPE_NUMBER = 1;
/**
* The type of default text size for this cue, which may be unset. One of {@link #TYPE_UNSET},
* {@link #TEXT_SIZE_TYPE_FRACTIONAL}, {@link #TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING} or {@link
* #TEXT_SIZE_TYPE_ABSOLUTE}.
*/
// @Target list includes both 'default' targets and TYPE_USE, to ensure backwards compatibility
// with Kotlin usages from before TYPE_USE was added.
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
@IntDef({
TYPE_UNSET,
TEXT_SIZE_TYPE_FRACTIONAL,
TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING,
TEXT_SIZE_TYPE_ABSOLUTE
})
public @interface TextSizeType {}
/** Text size is measured as a fraction of the viewport size minus the view padding. */
public static final int TEXT_SIZE_TYPE_FRACTIONAL = 0;
/** Text size is measured as a fraction of the viewport size, ignoring the view padding */
public static final int TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING = 1;
/** Text size is measured in number of pixels. */
public static final int TEXT_SIZE_TYPE_ABSOLUTE = 2;
/**
* The type of vertical layout for this cue, which may be unset (i.e. horizontal). One of {@link
* #TYPE_UNSET}, {@link #VERTICAL_TYPE_RL} or {@link #VERTICAL_TYPE_LR}.
*/
// @Target list includes both 'default' targets and TYPE_USE, to ensure backwards compatibility
// with Kotlin usages from before TYPE_USE was added.
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
@IntDef({
TYPE_UNSET,
VERTICAL_TYPE_RL,
VERTICAL_TYPE_LR,
})
public @interface VerticalType {}
/** Vertical right-to-left (e.g. for Japanese). */
public static final int VERTICAL_TYPE_RL = 1;
/** Vertical left-to-right (e.g. for Mongolian). */
public static final int VERTICAL_TYPE_LR = 2;
/**
* The cue text, or null if this is an image cue. Note the {@link CharSequence} may be decorated
* with styling spans.
*/
@Nullable public final CharSequence text;
/** The alignment of the cue text within the cue box, or null if the alignment is undefined. */
@Nullable public final Alignment textAlignment;
/**
* The alignment of multiple lines of text relative to the longest line, or null if the alignment
* is undefined.
*/
@Nullable public final Alignment multiRowAlignment;
/** The cue image, or null if this is a text cue. */
@Nullable public final Bitmap bitmap;
/**
* The position of the cue box within the viewport in the direction orthogonal to the writing
* direction (determined by {@link #verticalType}), or {@link #DIMEN_UNSET}. When set, the
* interpretation of the value depends on the value of {@link #lineType}.
*
* <p>The measurement direction depends on {@link #verticalType}:
*
* <ul>
* <li>For {@link #TYPE_UNSET} (i.e. horizontal), this is the vertical position relative to the
* top of the viewport.
* <li>For {@link #VERTICAL_TYPE_LR} this is the horizontal position relative to the left of the
* viewport.
* <li>For {@link #VERTICAL_TYPE_RL} this is the horizontal position relative to the right of
* the viewport.
* </ul>
*/
public final float line;
/**
* The type of the {@link #line} value.
*
* <ul>
* <li>{@link #LINE_TYPE_FRACTION} indicates that {@link #line} is a fractional position within
* the viewport (measured to the part of the cue box determined by {@link #lineAnchor}).
* <li>{@link #LINE_TYPE_NUMBER} indicates that {@link #line} is a viewport line number. The
* viewport is divided into lines (each equal in size to the first line of the cue box). The
* cue box is positioned to align with the viewport lines as follows:
* <ul>
* <li>{@link #lineAnchor}) is ignored.
* <li>When {@code line} is greater than or equal to 0 the first line in the cue box is
* aligned with a viewport line, with 0 meaning the first line of the viewport.
* <li>When {@code line} is negative the last line in the cue box is aligned with a
* viewport line, with -1 meaning the last line of the viewport.
* <li>For horizontal text the start and end of the viewport are the top and bottom
* respectively.
* </ul>
* </ul>
*/
public final @LineType int lineType;
/**
* The cue box anchor positioned by {@link #line} when {@link #lineType} is {@link
* #LINE_TYPE_FRACTION}.
*
* <p>One of:
*
* <ul>
* <li>{@link #ANCHOR_TYPE_START}
* <li>{@link #ANCHOR_TYPE_MIDDLE}
* <li>{@link #ANCHOR_TYPE_END}
* <li>{@link #TYPE_UNSET}
* </ul>
*
* <p>For the normal case of horizontal text, {@link #ANCHOR_TYPE_START}, {@link
* #ANCHOR_TYPE_MIDDLE} and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of
* the cue box respectively.
*/
public final @AnchorType int lineAnchor;
/**
* The fractional position of the {@link #positionAnchor} of the cue box within the viewport in
* the direction orthogonal to {@link #line}, or {@link #DIMEN_UNSET}.
*
* <p>The measurement direction depends on {@link #verticalType}.
*
* <ul>
* <li>For {@link #TYPE_UNSET} (i.e. horizontal), this is the horizontal position relative to
* the left of the viewport. Note that positioning is relative to the left of the viewport
* even in the case of right-to-left text.
* <li>For {@link #VERTICAL_TYPE_LR} and {@link #VERTICAL_TYPE_RL} (i.e. vertical), this is the
* vertical position relative to the top of the viewport.
* </ul>
*/
public final float position;
/**
* The cue box anchor positioned by {@link #position}. One of {@link #ANCHOR_TYPE_START}, {@link
* #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
*
* <p>For the normal case of horizontal text, {@link #ANCHOR_TYPE_START}, {@link
* #ANCHOR_TYPE_MIDDLE} and {@link #ANCHOR_TYPE_END} correspond to the left, middle and right of
* the cue box respectively.
*/
public final @AnchorType int positionAnchor;
/**
* The size of the cue box in the writing direction specified as a fraction of the viewport size
* in that direction, or {@link #DIMEN_UNSET}.
*/
public final float size;
/**
* The bitmap height as a fraction of the of the viewport size, or {@link #DIMEN_UNSET} if the
* bitmap should be displayed at its natural height given the bitmap dimensions and the specified
* {@link #size}.
*/
public final float bitmapHeight;
/** Specifies whether or not the {@link #windowColor} property is set. */
public final boolean windowColorSet;
/** The fill color of the window. */
public final int windowColor;
/**
* The default text size type for this cue's text, or {@link #TYPE_UNSET} if this cue has no
* default text size.
*/
public final @TextSizeType int textSizeType;
/**
* The default text size for this cue's text, or {@link #DIMEN_UNSET} if this cue has no default
* text size.
*/
public final float textSize;
/**
* The vertical formatting of this Cue, or {@link #TYPE_UNSET} if the cue has no vertical setting
* (and so should be horizontal).
*/
public final @VerticalType int verticalType;
/**
* The shear angle in degrees to be applied to this Cue, expressed in graphics coordinates. This
* results in a skew transform for the block along the inline progression axis.
*/
public final float shearDegrees;
private Cue(
@Nullable CharSequence text,
@Nullable Alignment textAlignment,
@Nullable Alignment multiRowAlignment,
@Nullable Bitmap bitmap,
float line,
@LineType int lineType,
@AnchorType int lineAnchor,
float position,
@AnchorType int positionAnchor,
@TextSizeType int textSizeType,
float textSize,
float size,
float bitmapHeight,
boolean windowColorSet,
int windowColor,
@VerticalType int verticalType,
float shearDegrees) {
// Exactly one of text or bitmap should be set.
if (text == null) {
Assertions.checkNotNull(bitmap);
} else {
Assertions.checkArgument(bitmap == null);
}
if (text instanceof Spanned) {
this.text = SpannedString.valueOf(text);
} else if (text != null) {
this.text = text.toString();
} else {
this.text = null;
}
this.textAlignment = textAlignment;
this.multiRowAlignment = multiRowAlignment;
this.bitmap = bitmap;
this.line = line;
this.lineType = lineType;
this.lineAnchor = lineAnchor;
this.position = position;
this.positionAnchor = positionAnchor;
this.size = size;
this.bitmapHeight = bitmapHeight;
this.windowColorSet = windowColorSet;
this.windowColor = windowColor;
this.textSizeType = textSizeType;
this.textSize = textSize;
this.verticalType = verticalType;
this.shearDegrees = shearDegrees;
}
/** Returns a new {@link Cue.Builder} initialized with the same values as this Cue. */
@UnstableApi
public Builder buildUpon() {
return new Cue.Builder(this);
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Cue that = (Cue) obj;
return TextUtils.equals(text, that.text)
&& textAlignment == that.textAlignment
&& multiRowAlignment == that.multiRowAlignment
&& (bitmap == null
? that.bitmap == null
: (that.bitmap != null && bitmap.sameAs(that.bitmap)))
&& line == that.line
&& lineType == that.lineType
&& lineAnchor == that.lineAnchor
&& position == that.position
&& positionAnchor == that.positionAnchor
&& size == that.size
&& bitmapHeight == that.bitmapHeight
&& windowColorSet == that.windowColorSet
&& windowColor == that.windowColor
&& textSizeType == that.textSizeType
&& textSize == that.textSize
&& verticalType == that.verticalType
&& shearDegrees == that.shearDegrees;
}
@Override
public int hashCode() {
return Objects.hashCode(
text,
textAlignment,
multiRowAlignment,
bitmap,
line,
lineType,
lineAnchor,
position,
positionAnchor,
size,
bitmapHeight,
windowColorSet,
windowColor,
textSizeType,
textSize,
verticalType,
shearDegrees);
}
/** A builder for {@link Cue} objects. */
@UnstableApi
public static final class Builder {
@Nullable private CharSequence text;
@Nullable private Bitmap bitmap;
@Nullable private Alignment textAlignment;
@Nullable private Alignment multiRowAlignment;
private float line;
private @LineType int lineType;
private @AnchorType int lineAnchor;
private float position;
private @AnchorType int positionAnchor;
private @TextSizeType int textSizeType;
private float textSize;
private float size;
private float bitmapHeight;
private boolean windowColorSet;
@ColorInt private int windowColor;
private @VerticalType int verticalType;
private float shearDegrees;
public Builder() {
text = null;
bitmap = null;
textAlignment = null;
multiRowAlignment = null;
line = DIMEN_UNSET;
lineType = TYPE_UNSET;
lineAnchor = TYPE_UNSET;
position = DIMEN_UNSET;
positionAnchor = TYPE_UNSET;
textSizeType = TYPE_UNSET;
textSize = DIMEN_UNSET;
size = DIMEN_UNSET;
bitmapHeight = DIMEN_UNSET;
windowColorSet = false;
windowColor = Color.BLACK;
verticalType = TYPE_UNSET;
}
private Builder(Cue cue) {
text = cue.text;
bitmap = cue.bitmap;
textAlignment = cue.textAlignment;
multiRowAlignment = cue.multiRowAlignment;
line = cue.line;
lineType = cue.lineType;
lineAnchor = cue.lineAnchor;
position = cue.position;
positionAnchor = cue.positionAnchor;
textSizeType = cue.textSizeType;
textSize = cue.textSize;
size = cue.size;
bitmapHeight = cue.bitmapHeight;
windowColorSet = cue.windowColorSet;
windowColor = cue.windowColor;
verticalType = cue.verticalType;
shearDegrees = cue.shearDegrees;
}
/**
* Sets the cue text.
*
* <p>Note that {@code text} may be decorated with styling spans.
*
* @see Cue#text
*/
@CanIgnoreReturnValue
public Builder setText(CharSequence text) {
this.text = text;
return this;
}
/**
* Gets the cue text.
*
* @see Cue#text
*/
@Pure
@Nullable
public CharSequence getText() {
return text;
}
/**
* Sets the cue image.
*
* @see Cue#bitmap
*/
@CanIgnoreReturnValue
public Builder setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
return this;
}
/**
* Gets the cue image.
*
* @see Cue#bitmap
*/
@Pure
@Nullable
public Bitmap getBitmap() {
return bitmap;
}
/**
* Sets the alignment of the cue text within the cue box.
*
* <p>Passing null means the alignment is undefined.
*
* @see Cue#textAlignment
*/
@CanIgnoreReturnValue
public Builder setTextAlignment(@Nullable Layout.Alignment textAlignment) {
this.textAlignment = textAlignment;
return this;
}
/**
* Gets the alignment of the cue text within the cue box, or null if the alignment is undefined.
*
* @see Cue#textAlignment
*/
@Pure
@Nullable
public Alignment getTextAlignment() {
return textAlignment;
}
/**
* Sets the multi-row alignment of the cue.
*
* <p>Passing null means the alignment is undefined.
*
* @see Cue#multiRowAlignment
*/
@CanIgnoreReturnValue
public Builder setMultiRowAlignment(@Nullable Layout.Alignment multiRowAlignment) {
this.multiRowAlignment = multiRowAlignment;
return this;
}
/**
* Sets the position of the cue box within the viewport in the direction orthogonal to the
* writing direction.
*
* @see Cue#line
* @see Cue#lineType
*/
@CanIgnoreReturnValue
public Builder setLine(float line, @LineType int lineType) {
this.line = line;
this.lineType = lineType;
return this;
}
/**
* Gets the position of the {@code lineAnchor} of the cue box within the viewport in the
* direction orthogonal to the writing direction.
*
* @see Cue#line
*/
@Pure
public float getLine() {
return line;
}
/**
* Gets the type of the value of {@link #getLine()}.
*
* @see Cue#lineType
*/
@Pure
public @LineType int getLineType() {
return lineType;
}
/**
* Sets the cue box anchor positioned by {@link #setLine(float, int) line}.
*
* @see Cue#lineAnchor
*/
@CanIgnoreReturnValue
public Builder setLineAnchor(@AnchorType int lineAnchor) {
this.lineAnchor = lineAnchor;
return this;
}
/**
* Gets the cue box anchor positioned by {@link #setLine(float, int) line}.
*
* @see Cue#lineAnchor
*/
@Pure
public @AnchorType int getLineAnchor() {
return lineAnchor;
}
/**
* Sets the fractional position of the {@link #setPositionAnchor(int) positionAnchor} of the cue
* box within the viewport in the direction orthogonal to {@link #setLine(float, int) line}.
*
* @see Cue#position
*/
@CanIgnoreReturnValue
public Builder setPosition(float position) {
this.position = position;
return this;
}
/**
* Gets the fractional position of the {@link #setPositionAnchor(int) positionAnchor} of the cue
* box within the viewport in the direction orthogonal to {@link #setLine(float, int) line}.
*
* @see Cue#position
*/
@Pure
public float getPosition() {
return position;
}
/**
* Sets the cue box anchor positioned by {@link #setPosition(float) position}.
*
* @see Cue#positionAnchor
*/
@CanIgnoreReturnValue
public Builder setPositionAnchor(@AnchorType int positionAnchor) {
this.positionAnchor = positionAnchor;
return this;
}
/**
* Gets the cue box anchor positioned by {@link #setPosition(float) position}.
*
* @see Cue#positionAnchor
*/
@Pure
public @AnchorType int getPositionAnchor() {
return positionAnchor;
}
/**
* Sets the default text size and type for this cue's text.
*
* @see Cue#textSize
* @see Cue#textSizeType
*/
@CanIgnoreReturnValue
public Builder setTextSize(float textSize, @TextSizeType int textSizeType) {
this.textSize = textSize;
this.textSizeType = textSizeType;
return this;
}
/**
* Gets the default text size type for this cue's text.
*
* @see Cue#textSizeType
*/
@Pure
public @TextSizeType int getTextSizeType() {
return textSizeType;
}
/**
* Gets the default text size for this cue's text.
*
* @see Cue#textSize
*/
@Pure
public float getTextSize() {
return textSize;
}
/**
* Sets the size of the cue box in the writing direction specified as a fraction of the viewport
* size in that direction.
*
* @see Cue#size
*/
@CanIgnoreReturnValue
public Builder setSize(float size) {
this.size = size;
return this;
}
/**
* Gets the size of the cue box in the writing direction specified as a fraction of the viewport
* size in that direction.
*
* @see Cue#size
*/
@Pure
public float getSize() {
return size;
}
/**
* Sets the bitmap height as a fraction of the viewport size.
*
* @see Cue#bitmapHeight
*/
@CanIgnoreReturnValue
public Builder setBitmapHeight(float bitmapHeight) {
this.bitmapHeight = bitmapHeight;
return this;
}
/**
* Gets the bitmap height as a fraction of the viewport size.
*
* @see Cue#bitmapHeight
*/
@Pure
public float getBitmapHeight() {
return bitmapHeight;
}
/**
* Sets the fill color of the window.
*
* <p>Also sets {@link Cue#windowColorSet} to true.
*
* @see Cue#windowColor
* @see Cue#windowColorSet
*/
@CanIgnoreReturnValue
public Builder setWindowColor(@ColorInt int windowColor) {
this.windowColor = windowColor;
this.windowColorSet = true;
return this;
}
/** Sets {@link Cue#windowColorSet} to false. */
@CanIgnoreReturnValue
public Builder clearWindowColor() {
this.windowColorSet = false;
return this;
}
/**
* Returns true if the fill color of the window is set.
*
* @see Cue#windowColorSet
*/
public boolean isWindowColorSet() {
return windowColorSet;
}
/**
* Gets the fill color of the window.
*
* @see Cue#windowColor
*/
@Pure
@ColorInt
public int getWindowColor() {
return windowColor;
}
/**
* Sets the vertical formatting for this Cue.
*
* @see Cue#verticalType
*/
@CanIgnoreReturnValue
public Builder setVerticalType(@VerticalType int verticalType) {
this.verticalType = verticalType;
return this;
}
/** Sets the shear angle for this Cue. */
@CanIgnoreReturnValue
public Builder setShearDegrees(float shearDegrees) {
this.shearDegrees = shearDegrees;
return this;
}
/**
* Gets the vertical formatting for this Cue.
*
* @see Cue#verticalType
*/
@Pure
public @VerticalType int getVerticalType() {
return verticalType;
}
/** Build the cue. */
public Cue build() {
return new Cue(
text,
textAlignment,
multiRowAlignment,
bitmap,
line,
lineType,
lineAnchor,
position,
positionAnchor,
textSizeType,
textSize,
size,
bitmapHeight,
windowColorSet,
windowColor,
verticalType,
shearDegrees);
}
}
private static final String FIELD_TEXT = Util.intToStringMaxRadix(0);
private static final String FIELD_CUSTOM_SPANS = Util.intToStringMaxRadix(17);
private static final String FIELD_TEXT_ALIGNMENT = Util.intToStringMaxRadix(1);
private static final String FIELD_MULTI_ROW_ALIGNMENT = Util.intToStringMaxRadix(2);
private static final String FIELD_BITMAP_PARCELABLE = Util.intToStringMaxRadix(3);
private static final String FIELD_BITMAP_BYTES = Util.intToStringMaxRadix(18);
private static final String FIELD_LINE = Util.intToStringMaxRadix(4);
private static final String FIELD_LINE_TYPE = Util.intToStringMaxRadix(5);
private static final String FIELD_LINE_ANCHOR = Util.intToStringMaxRadix(6);
private static final String FIELD_POSITION = Util.intToStringMaxRadix(7);
private static final String FIELD_POSITION_ANCHOR = Util.intToStringMaxRadix(8);
private static final String FIELD_TEXT_SIZE_TYPE = Util.intToStringMaxRadix(9);
private static final String FIELD_TEXT_SIZE = Util.intToStringMaxRadix(10);
private static final String FIELD_SIZE = Util.intToStringMaxRadix(11);
private static final String FIELD_BITMAP_HEIGHT = Util.intToStringMaxRadix(12);
private static final String FIELD_WINDOW_COLOR = Util.intToStringMaxRadix(13);
private static final String FIELD_WINDOW_COLOR_SET = Util.intToStringMaxRadix(14);
private static final String FIELD_VERTICAL_TYPE = Util.intToStringMaxRadix(15);
private static final String FIELD_SHEAR_DEGREES = Util.intToStringMaxRadix(16);
/**
* Returns a {@link Bundle} that can be serialized to bytes.
*
* <p>Prefer the more efficient {@link #toBinderBasedBundle()} if the result doesn't need to be
* serialized.
*
* <p>The {@link Bundle} returned from this method must not be passed to other processes that
* might be using a different version of the media3 library.
*/
@UnstableApi
public Bundle toSerializableBundle() {
Bundle bundle = toBundleWithoutBitmap();
if (bitmap != null) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
// The PNG format is lossless, and the quality parameter is ignored.
checkState(bitmap.compress(Bitmap.CompressFormat.PNG, /* quality= */ 0, output));
bundle.putByteArray(FIELD_BITMAP_BYTES, output.toByteArray());
}
return bundle;
}
/**
* Returns a {@link Bundle} that may contain {@link Binder} references, meaning it cannot be
* safely serialized to bytes.
*
* <p>The {@link Bundle} returned from this method can be safely sent between processes and parsed
* by older versions of the media3 library.
*
* <p>Use {@link #toSerializableBundle()} to get a {@link Bundle} that can be safely serialized.
*/
@UnstableApi
public Bundle toBinderBasedBundle() {
Bundle bundle = toBundleWithoutBitmap();
if (bitmap != null) {
bundle.putParcelable(FIELD_BITMAP_PARCELABLE, bitmap);
}
return bundle;
}
/**
* @deprecated Use {@link #toSerializableBundle()} or {@link #toBinderBasedBundle()} instead.
*/
@UnstableApi
@Deprecated
public Bundle toBundle() {
return toBinderBasedBundle();
}
private Bundle toBundleWithoutBitmap() {
Bundle bundle = new Bundle();
if (text != null) {
bundle.putCharSequence(FIELD_TEXT, text);
if (text instanceof Spanned) {
ArrayList<Bundle> customSpanBundles = bundleCustomSpans((Spanned) text);
if (!customSpanBundles.isEmpty()) {
bundle.putParcelableArrayList(FIELD_CUSTOM_SPANS, customSpanBundles);
}
}
}
bundle.putSerializable(FIELD_TEXT_ALIGNMENT, textAlignment);
bundle.putSerializable(FIELD_MULTI_ROW_ALIGNMENT, multiRowAlignment);
bundle.putFloat(FIELD_LINE, line);
bundle.putInt(FIELD_LINE_TYPE, lineType);
bundle.putInt(FIELD_LINE_ANCHOR, lineAnchor);
bundle.putFloat(FIELD_POSITION, position);
bundle.putInt(FIELD_POSITION_ANCHOR, positionAnchor);
bundle.putInt(FIELD_TEXT_SIZE_TYPE, textSizeType);
bundle.putFloat(FIELD_TEXT_SIZE, textSize);
bundle.putFloat(FIELD_SIZE, size);
bundle.putFloat(FIELD_BITMAP_HEIGHT, bitmapHeight);
bundle.putBoolean(FIELD_WINDOW_COLOR_SET, windowColorSet);
bundle.putInt(FIELD_WINDOW_COLOR, windowColor);
bundle.putInt(FIELD_VERTICAL_TYPE, verticalType);
bundle.putFloat(FIELD_SHEAR_DEGREES, shearDegrees);
return bundle;
}
/** Restores a cue from a {@link Bundle}. */
@UnstableApi
public static Cue fromBundle(Bundle bundle) {
Builder builder = new Builder();
@Nullable CharSequence text = bundle.getCharSequence(FIELD_TEXT);
if (text != null) {
builder.setText(text);
@Nullable
ArrayList<Bundle> customSpanBundles = bundle.getParcelableArrayList(FIELD_CUSTOM_SPANS);
if (customSpanBundles != null) {
SpannableString textWithCustomSpans = SpannableString.valueOf(text);
for (Bundle customSpanBundle : customSpanBundles) {
CustomSpanBundler.unbundleAndApplyCustomSpan(customSpanBundle, textWithCustomSpans);
}
builder.setText(textWithCustomSpans);
}
}
@Nullable Alignment textAlignment = (Alignment) bundle.getSerializable(FIELD_TEXT_ALIGNMENT);
if (textAlignment != null) {
builder.setTextAlignment(textAlignment);
}
@Nullable
Alignment multiRowAlignment = (Alignment) bundle.getSerializable(FIELD_MULTI_ROW_ALIGNMENT);
if (multiRowAlignment != null) {
builder.setMultiRowAlignment(multiRowAlignment);
}
@Nullable Bitmap bitmap = bundle.getParcelable(FIELD_BITMAP_PARCELABLE);
if (bitmap != null) {
builder.setBitmap(bitmap);
} else {
@Nullable byte[] bitmapBytes = bundle.getByteArray(FIELD_BITMAP_BYTES);
if (bitmapBytes != null) {
builder.setBitmap(
BitmapFactory.decodeByteArray(bitmapBytes, /* offset= */ 0, bitmapBytes.length));
}
}
if (bundle.containsKey(FIELD_LINE) && bundle.containsKey(FIELD_LINE_TYPE)) {
builder.setLine(bundle.getFloat(FIELD_LINE), bundle.getInt(FIELD_LINE_TYPE));
}
if (bundle.containsKey(FIELD_LINE_ANCHOR)) {
builder.setLineAnchor(bundle.getInt(FIELD_LINE_ANCHOR));
}
if (bundle.containsKey(FIELD_POSITION)) {
builder.setPosition(bundle.getFloat(FIELD_POSITION));
}
if (bundle.containsKey(FIELD_POSITION_ANCHOR)) {
builder.setPositionAnchor(bundle.getInt(FIELD_POSITION_ANCHOR));
}
if (bundle.containsKey(FIELD_TEXT_SIZE) && bundle.containsKey(FIELD_TEXT_SIZE_TYPE)) {
builder.setTextSize(bundle.getFloat(FIELD_TEXT_SIZE), bundle.getInt(FIELD_TEXT_SIZE_TYPE));
}
if (bundle.containsKey(FIELD_SIZE)) {
builder.setSize(bundle.getFloat(FIELD_SIZE));
}
if (bundle.containsKey(FIELD_BITMAP_HEIGHT)) {
builder.setBitmapHeight(bundle.getFloat(FIELD_BITMAP_HEIGHT));
}
if (bundle.containsKey(FIELD_WINDOW_COLOR)) {
builder.setWindowColor(bundle.getInt(FIELD_WINDOW_COLOR));
}
if (!bundle.getBoolean(FIELD_WINDOW_COLOR_SET, /* defaultValue= */ false)) {
builder.clearWindowColor();
}
if (bundle.containsKey(FIELD_VERTICAL_TYPE)) {
builder.setVerticalType(bundle.getInt(FIELD_VERTICAL_TYPE));
}
if (bundle.containsKey(FIELD_SHEAR_DEGREES)) {
builder.setShearDegrees(bundle.getFloat(FIELD_SHEAR_DEGREES));
}
return builder.build();
}
}