From 2a9fcaadbcb9682f5ee82b8b06f867a9e91163b3 Mon Sep 17 00:00:00 2001 From: peerless2012 Date: Thu, 13 Feb 2025 00:38:26 +0800 Subject: [PATCH 1/4] Add layer in cue and output. --- .../java/androidx/media3/common/text/Cue.java | 40 +++++++++++++++++-- .../exoplayer/text/MergingCuesResolver.java | 9 ++++- .../media3/extractor/text/CuesWithTiming.java | 9 ++++- .../androidx/media3/ui/SubtitlePainter.java | 5 ++- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/text/Cue.java b/libraries/common/src/main/java/androidx/media3/common/text/Cue.java index 719a1889fb5..21a286c1a99 100644 --- a/libraries/common/src/main/java/androidx/media3/common/text/Cue.java +++ b/libraries/common/src/main/java/androidx/media3/common/text/Cue.java @@ -309,6 +309,11 @@ public final class Cue { */ public final float shearDegrees; + /** + * The layer for cue, the larger cue will render above the smaller cue. + */ + public final int layer; + private Cue( @Nullable CharSequence text, @Nullable Alignment textAlignment, @@ -326,7 +331,8 @@ private Cue( boolean windowColorSet, int windowColor, @VerticalType int verticalType, - float shearDegrees) { + float shearDegrees, + int layer) { // Exactly one of text or bitmap should be set. if (text == null) { Assertions.checkNotNull(bitmap); @@ -356,6 +362,7 @@ private Cue( this.textSize = textSize; this.verticalType = verticalType; this.shearDegrees = shearDegrees; + this.layer = layer; } /** Returns a new {@link Cue.Builder} initialized with the same values as this Cue. */ @@ -391,7 +398,8 @@ public boolean equals(@Nullable Object obj) { && textSizeType == that.textSizeType && textSize == that.textSize && verticalType == that.verticalType - && shearDegrees == that.shearDegrees; + && shearDegrees == that.shearDegrees + && layer == that.layer; } @Override @@ -413,7 +421,8 @@ public int hashCode() { textSizeType, textSize, verticalType, - shearDegrees); + shearDegrees, + layer); } /** A builder for {@link Cue} objects. */ @@ -436,6 +445,7 @@ public static final class Builder { @ColorInt private int windowColor; private @VerticalType int verticalType; private float shearDegrees; + private int layer; public Builder() { text = null; @@ -474,6 +484,7 @@ private Builder(Cue cue) { windowColor = cue.windowColor; verticalType = cue.verticalType; shearDegrees = cue.shearDegrees; + layer = cue.layer; } /** @@ -806,6 +817,21 @@ public Builder setShearDegrees(float shearDegrees) { return verticalType; } + /** Sets the layer for this Cue. */ + @CanIgnoreReturnValue + public Builder setLayer(int layer) { + this.layer = layer; + return this; + } + + /** + * Gets the layer for this Cue. + */ + @Pure + public @VerticalType int getLayer() { + return layer; + } + /** Build the cue. */ public Cue build() { return new Cue( @@ -825,7 +851,8 @@ public Cue build() { windowColorSet, windowColor, verticalType, - shearDegrees); + shearDegrees, + layer); } } @@ -848,6 +875,7 @@ public Cue build() { 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); + private static final String FIELD_LAYER = Util.intToStringMaxRadix(19); /** * Returns a {@link Bundle} that can be serialized to bytes. @@ -923,6 +951,7 @@ private Bundle toBundleWithoutBitmap() { bundle.putInt(FIELD_WINDOW_COLOR, windowColor); bundle.putInt(FIELD_VERTICAL_TYPE, verticalType); bundle.putFloat(FIELD_SHEAR_DEGREES, shearDegrees); + bundle.putInt(FIELD_LAYER, layer); return bundle; } @@ -995,6 +1024,9 @@ public static Cue fromBundle(Bundle bundle) { if (bundle.containsKey(FIELD_SHEAR_DEGREES)) { builder.setShearDegrees(bundle.getFloat(FIELD_SHEAR_DEGREES)); } + if (bundle.containsKey(FIELD_LAYER)) { + builder.setLayer(bundle.getInt(FIELD_LAYER)); + } return builder.build(); } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java index f015f059fc6..cb4b712441f 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java @@ -52,6 +52,12 @@ .compound( Ordering.natural().reverse().onResultOf((CuesWithTiming c) -> c.durationUs)); + /** + * An {@link Ordering} which sorts cues in ascending layer priority + */ + private static final Ordering CUES_LAYER_PRIORITY_COMPARATOR = + Ordering.natural().onResultOf(c -> c.layer); + /** Sorted by {@link CuesWithTiming#startTimeUs} ascending. */ private final List cuesWithTimingList; @@ -97,7 +103,8 @@ public ImmutableList getCuesAtTimeUs(long timeUs) { for (int i = 0; i < sortedResult.size(); i++) { result.addAll(sortedResult.get(i).cues); } - return result.build(); + // sort by layer + return ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, result.build()); } @Override diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java index cb8a6ea8f00..c8f250b700b 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java @@ -21,12 +21,19 @@ import androidx.media3.common.text.Cue; import androidx.media3.common.util.UnstableApi; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Ordering; import java.util.List; /** A list of {@link Cue} instances with a start time and duration. */ @UnstableApi public class CuesWithTiming { + /** + * An {@link Ordering} which sorts cues in ascending layer priority + */ + private static final Ordering CUES_LAYER_PRIORITY_COMPARATOR = + Ordering.natural().onResultOf(c -> c.layer); + /** The cues to show on screen. */ public final ImmutableList cues; @@ -68,7 +75,7 @@ public class CuesWithTiming { /** Creates an instance. */ public CuesWithTiming(List cues, long startTimeUs, long durationUs) { - this.cues = ImmutableList.copyOf(cues); + this.cues = ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, cues); this.startTimeUs = startTimeUs; this.durationUs = durationUs; this.endTimeUs = diff --git a/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java b/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java index 697024f1d8f..45932f62888 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java @@ -85,6 +85,7 @@ private int parentTop; private int parentRight; private int parentBottom; + private int cueLayer; // Derived drawing variables. private @MonotonicNonNull StaticLayout textLayout; @@ -184,7 +185,8 @@ public void draw( && this.parentLeft == cueBoxLeft && this.parentTop == cueBoxTop && this.parentRight == cueBoxRight - && this.parentBottom == cueBoxBottom) { + && this.parentBottom == cueBoxBottom + && this.cueLayer == cue.layer) { // We can use the cached layout. drawLayout(canvas, isTextCue); return; @@ -213,6 +215,7 @@ public void draw( this.parentTop = cueBoxTop; this.parentRight = cueBoxRight; this.parentBottom = cueBoxBottom; + this.cueLayer = cue.layer; if (isTextCue) { Assertions.checkNotNull(cueText); From c04a68d4791d66be8d7b391da0b89af9b35e3ca9 Mon Sep 17 00:00:00 2001 From: peerless2012 Date: Thu, 13 Feb 2025 00:40:03 +0800 Subject: [PATCH 2/4] Add layer support for ssa parser. --- demos/main/src/main/assets/media.exolist.json | 7 +++++ .../extractor/text/ssa/SsaDialogueFormat.java | 10 +++++-- .../media3/extractor/text/ssa/SsaParser.java | 26 +++++++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/demos/main/src/main/assets/media.exolist.json b/demos/main/src/main/assets/media.exolist.json index d3a7e2a953e..e89c9fa676c 100644 --- a/demos/main/src/main/assets/media.exolist.json +++ b/demos/main/src/main/assets/media.exolist.json @@ -690,6 +690,13 @@ "subtitle_mime_type": "text/x-ssa", "subtitle_language": "en" }, + { + "name": "SubStation Layer Render", + "uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/video-avc-baseline-480.mp4", + "subtitle_uri": "https://storage.googleapis.com/exoplayer-test-media-1/ssa/test-subs-layer.ass", + "subtitle_mime_type": "text/x-ssa", + "subtitle_language": "en" + }, { "name": "MPEG-4 Timed Text", "uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/dizzy-with-tx3g.mp4" diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaDialogueFormat.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaDialogueFormat.java index 360ab05d520..f9b1128b440 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaDialogueFormat.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaDialogueFormat.java @@ -32,6 +32,7 @@ */ /* package */ final class SsaDialogueFormat { + public final int layerIndex; public final int startTimeIndex; public final int endTimeIndex; public final int styleIndex; @@ -39,7 +40,8 @@ public final int length; private SsaDialogueFormat( - int startTimeIndex, int endTimeIndex, int styleIndex, int textIndex, int length) { + int layerIndex, int startTimeIndex, int endTimeIndex, int styleIndex, int textIndex, int length) { + this.layerIndex = layerIndex; this.startTimeIndex = startTimeIndex; this.endTimeIndex = endTimeIndex; this.styleIndex = styleIndex; @@ -54,6 +56,7 @@ private SsaDialogueFormat( */ @Nullable public static SsaDialogueFormat fromFormatLine(String formatLine) { + int layerIndex = C.INDEX_UNSET; int startTimeIndex = C.INDEX_UNSET; int endTimeIndex = C.INDEX_UNSET; int styleIndex = C.INDEX_UNSET; @@ -62,6 +65,9 @@ public static SsaDialogueFormat fromFormatLine(String formatLine) { String[] keys = TextUtils.split(formatLine.substring(FORMAT_LINE_PREFIX.length()), ","); for (int i = 0; i < keys.length; i++) { switch (Ascii.toLowerCase(keys[i].trim())) { + case "layer": + layerIndex = i; + break; case "start": startTimeIndex = i; break; @@ -79,7 +85,7 @@ public static SsaDialogueFormat fromFormatLine(String formatLine) { return (startTimeIndex != C.INDEX_UNSET && endTimeIndex != C.INDEX_UNSET && textIndex != C.INDEX_UNSET) - ? new SsaDialogueFormat(startTimeIndex, endTimeIndex, styleIndex, textIndex, keys.length) + ? new SsaDialogueFormat(layerIndex, startTimeIndex, endTimeIndex, styleIndex, textIndex, keys.length) : null; } } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java index f387bb9f6c1..7701573ebe4 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java @@ -327,6 +327,14 @@ private void parseDialogueLine( return; } + int layer = 0; + if (format.layerIndex != C.INDEX_UNSET) { + layer = parseInt(lineValues[format.layerIndex]); + if (layer == C.LENGTH_UNSET) { + layer = 0; + } + } + long startTimeUs = parseTimecodeUs(lineValues[format.startTimeIndex]); if (startTimeUs == C.TIME_UNSET) { Log.w(TAG, "Skipping invalid timing: " + dialogueLine); @@ -351,7 +359,7 @@ private void parseDialogueLine( .replace("\\N", "\n") .replace("\\n", "\n") .replace("\\h", "\u00A0"); - Cue cue = createCue(text, style, styleOverrides, screenWidth, screenHeight); + Cue cue = createCue(text, layer, style, styleOverrides, screenWidth, screenHeight); int startTimeIndex = addCuePlacerholderByTime(startTimeUs, cueTimesUs, cues); int endTimeIndex = addCuePlacerholderByTime(endTimeUs, cueTimesUs, cues); @@ -361,6 +369,19 @@ private void parseDialogueLine( } } + /** + * Parse int in SSA. + * @param intString The string to parse. + * @return The parsed int. + */ + private static int parseInt(String intString) { + try { + return Integer.parseInt(intString.trim()); + } catch (Exception exception) { + return C.LENGTH_UNSET; + } + } + /** * Parses an SSA timecode string. * @@ -382,12 +403,13 @@ private static long parseTimecodeUs(String timeString) { private static Cue createCue( String text, + int layer, @Nullable SsaStyle style, SsaStyle.Overrides styleOverrides, float screenWidth, float screenHeight) { SpannableString spannableText = new SpannableString(text); - Cue.Builder cue = new Cue.Builder().setText(spannableText); + Cue.Builder cue = new Cue.Builder().setText(spannableText).setLayer(layer); if (style != null) { if (style.primaryColor != null) { From 48329f110469efe404407d26a5af08c7afdfc6d2 Mon Sep 17 00:00:00 2001 From: peerless2012 Date: Wed, 26 Feb 2025 14:58:50 +0800 Subject: [PATCH 3/4] Move sort by layer to CueGroup. --- .../java/androidx/media3/common/text/CueGroup.java | 9 ++++++++- .../media3/exoplayer/text/MergingCuesResolver.java | 9 +-------- .../androidx/media3/extractor/text/CuesWithTiming.java | 10 +--------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java b/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java index 30ab4f31f3f..8a4df59e48c 100644 --- a/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java +++ b/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java @@ -23,12 +23,19 @@ import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Ordering; import java.util.ArrayList; import java.util.List; /** Class to represent the state of active {@link Cue Cues} at a particular time. */ public final class CueGroup { + /** + * An {@link Ordering} which sorts cues in ascending layer priority + */ + private static final Ordering CUES_LAYER_PRIORITY_COMPARATOR = + Ordering.natural().onResultOf(c -> c.layer); + /** An empty group with no {@link Cue Cues} and presentation time of zero. */ @UnstableApi public static final CueGroup EMPTY_TIME_ZERO = @@ -54,7 +61,7 @@ public final class CueGroup { /** Creates a CueGroup. */ @UnstableApi public CueGroup(List cues, long presentationTimeUs) { - this.cues = ImmutableList.copyOf(cues); + this.cues = ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, cues); this.presentationTimeUs = presentationTimeUs; } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java index cb4b712441f..f015f059fc6 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/MergingCuesResolver.java @@ -52,12 +52,6 @@ .compound( Ordering.natural().reverse().onResultOf((CuesWithTiming c) -> c.durationUs)); - /** - * An {@link Ordering} which sorts cues in ascending layer priority - */ - private static final Ordering CUES_LAYER_PRIORITY_COMPARATOR = - Ordering.natural().onResultOf(c -> c.layer); - /** Sorted by {@link CuesWithTiming#startTimeUs} ascending. */ private final List cuesWithTimingList; @@ -103,8 +97,7 @@ public ImmutableList getCuesAtTimeUs(long timeUs) { for (int i = 0; i < sortedResult.size(); i++) { result.addAll(sortedResult.get(i).cues); } - // sort by layer - return ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, result.build()); + return result.build(); } @Override diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java index c8f250b700b..4dd2ffe071d 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/CuesWithTiming.java @@ -21,19 +21,11 @@ import androidx.media3.common.text.Cue; import androidx.media3.common.util.UnstableApi; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Ordering; import java.util.List; /** A list of {@link Cue} instances with a start time and duration. */ @UnstableApi public class CuesWithTiming { - - /** - * An {@link Ordering} which sorts cues in ascending layer priority - */ - private static final Ordering CUES_LAYER_PRIORITY_COMPARATOR = - Ordering.natural().onResultOf(c -> c.layer); - /** The cues to show on screen. */ public final ImmutableList cues; @@ -75,7 +67,7 @@ public class CuesWithTiming { /** Creates an instance. */ public CuesWithTiming(List cues, long startTimeUs, long durationUs) { - this.cues = ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, cues); + this.cues = ImmutableList.copyOf(cues); this.startTimeUs = startTimeUs; this.durationUs = durationUs; this.endTimeUs = From 49daeaac80bed38ed9a2a67f3c49a3404df91472 Mon Sep 17 00:00:00 2001 From: peerless2012 Date: Wed, 26 Feb 2025 15:14:00 +0800 Subject: [PATCH 4/4] Rename layer in Cue to zIndex, and remove zIndex in SubtitlePainter. --- .../java/androidx/media3/common/text/Cue.java | 38 +++++++++---------- .../androidx/media3/common/text/CueGroup.java | 8 ++-- .../media3/extractor/text/ssa/SsaParser.java | 4 +- .../androidx/media3/ui/SubtitlePainter.java | 5 +-- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/text/Cue.java b/libraries/common/src/main/java/androidx/media3/common/text/Cue.java index 21a286c1a99..8af7c2c47b8 100644 --- a/libraries/common/src/main/java/androidx/media3/common/text/Cue.java +++ b/libraries/common/src/main/java/androidx/media3/common/text/Cue.java @@ -310,9 +310,9 @@ public final class Cue { public final float shearDegrees; /** - * The layer for cue, the larger cue will render above the smaller cue. + * The z index for cue, the larger index will render above the smaller index. */ - public final int layer; + public final int zIndex; private Cue( @Nullable CharSequence text, @@ -332,7 +332,7 @@ private Cue( int windowColor, @VerticalType int verticalType, float shearDegrees, - int layer) { + int zIndex) { // Exactly one of text or bitmap should be set. if (text == null) { Assertions.checkNotNull(bitmap); @@ -362,7 +362,7 @@ private Cue( this.textSize = textSize; this.verticalType = verticalType; this.shearDegrees = shearDegrees; - this.layer = layer; + this.zIndex = zIndex; } /** Returns a new {@link Cue.Builder} initialized with the same values as this Cue. */ @@ -399,7 +399,7 @@ public boolean equals(@Nullable Object obj) { && textSize == that.textSize && verticalType == that.verticalType && shearDegrees == that.shearDegrees - && layer == that.layer; + && zIndex == that.zIndex; } @Override @@ -422,7 +422,7 @@ public int hashCode() { textSize, verticalType, shearDegrees, - layer); + zIndex); } /** A builder for {@link Cue} objects. */ @@ -445,7 +445,7 @@ public static final class Builder { @ColorInt private int windowColor; private @VerticalType int verticalType; private float shearDegrees; - private int layer; + private int zIndex; public Builder() { text = null; @@ -484,7 +484,7 @@ private Builder(Cue cue) { windowColor = cue.windowColor; verticalType = cue.verticalType; shearDegrees = cue.shearDegrees; - layer = cue.layer; + zIndex = cue.zIndex; } /** @@ -817,19 +817,19 @@ public Builder setShearDegrees(float shearDegrees) { return verticalType; } - /** Sets the layer for this Cue. */ + /** Sets the zIndex for this Cue. */ @CanIgnoreReturnValue - public Builder setLayer(int layer) { - this.layer = layer; + public Builder setZIndex(int zIndex) { + this.zIndex = zIndex; return this; } /** - * Gets the layer for this Cue. + * Gets the zIndex for this Cue. */ @Pure - public @VerticalType int getLayer() { - return layer; + public int getZIndex() { + return zIndex; } /** Build the cue. */ @@ -852,7 +852,7 @@ public Cue build() { windowColor, verticalType, shearDegrees, - layer); + zIndex); } } @@ -875,7 +875,7 @@ public Cue build() { 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); - private static final String FIELD_LAYER = Util.intToStringMaxRadix(19); + private static final String FIELD_Z_INDEX = Util.intToStringMaxRadix(19); /** * Returns a {@link Bundle} that can be serialized to bytes. @@ -951,7 +951,7 @@ private Bundle toBundleWithoutBitmap() { bundle.putInt(FIELD_WINDOW_COLOR, windowColor); bundle.putInt(FIELD_VERTICAL_TYPE, verticalType); bundle.putFloat(FIELD_SHEAR_DEGREES, shearDegrees); - bundle.putInt(FIELD_LAYER, layer); + bundle.putInt(FIELD_Z_INDEX, zIndex); return bundle; } @@ -1024,8 +1024,8 @@ public static Cue fromBundle(Bundle bundle) { if (bundle.containsKey(FIELD_SHEAR_DEGREES)) { builder.setShearDegrees(bundle.getFloat(FIELD_SHEAR_DEGREES)); } - if (bundle.containsKey(FIELD_LAYER)) { - builder.setLayer(bundle.getInt(FIELD_LAYER)); + if (bundle.containsKey(FIELD_Z_INDEX)) { + builder.setZIndex(bundle.getInt(FIELD_Z_INDEX)); } return builder.build(); } diff --git a/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java b/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java index 8a4df59e48c..e38a42d3cdb 100644 --- a/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java +++ b/libraries/common/src/main/java/androidx/media3/common/text/CueGroup.java @@ -31,10 +31,10 @@ public final class CueGroup { /** - * An {@link Ordering} which sorts cues in ascending layer priority + * An {@link Ordering} which sorts cues in ascending zIndex priority */ - private static final Ordering CUES_LAYER_PRIORITY_COMPARATOR = - Ordering.natural().onResultOf(c -> c.layer); + private static final Ordering CUES_PRIORITY_COMPARATOR = + Ordering.natural().onResultOf(c -> c.zIndex); /** An empty group with no {@link Cue Cues} and presentation time of zero. */ @UnstableApi @@ -61,7 +61,7 @@ public final class CueGroup { /** Creates a CueGroup. */ @UnstableApi public CueGroup(List cues, long presentationTimeUs) { - this.cues = ImmutableList.sortedCopyOf(CUES_LAYER_PRIORITY_COMPARATOR, cues); + this.cues = ImmutableList.sortedCopyOf(CUES_PRIORITY_COMPARATOR, cues); this.presentationTimeUs = presentationTimeUs; } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java index 7701573ebe4..3bf363c5dca 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ssa/SsaParser.java @@ -409,7 +409,9 @@ private static Cue createCue( float screenWidth, float screenHeight) { SpannableString spannableText = new SpannableString(text); - Cue.Builder cue = new Cue.Builder().setText(spannableText).setLayer(layer); + Cue.Builder cue = new Cue.Builder() + .setText(spannableText) + .setZIndex(layer); if (style != null) { if (style.primaryColor != null) { diff --git a/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java b/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java index 45932f62888..697024f1d8f 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/SubtitlePainter.java @@ -85,7 +85,6 @@ private int parentTop; private int parentRight; private int parentBottom; - private int cueLayer; // Derived drawing variables. private @MonotonicNonNull StaticLayout textLayout; @@ -185,8 +184,7 @@ public void draw( && this.parentLeft == cueBoxLeft && this.parentTop == cueBoxTop && this.parentRight == cueBoxRight - && this.parentBottom == cueBoxBottom - && this.cueLayer == cue.layer) { + && this.parentBottom == cueBoxBottom) { // We can use the cached layout. drawLayout(canvas, isTextCue); return; @@ -215,7 +213,6 @@ public void draw( this.parentTop = cueBoxTop; this.parentRight = cueBoxRight; this.parentBottom = cueBoxBottom; - this.cueLayer = cue.layer; if (isTextCue) { Assertions.checkNotNull(cueText);