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 6fc1a5b9e3..cb8a6ea8f0 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
@@ -51,10 +51,29 @@ public class CuesWithTiming {
*/
public final long durationUs;
+ /**
+ * The time at which {@link #cues} should stop being shown on screen, in microseconds, or {@link
+ * C#TIME_UNSET} if not known.
+ *
+ *
The time base of this is the same as {@link #startTimeUs}.
+ *
+ *
If {@link Format#cueReplacementBehavior} is {@link Format#CUE_REPLACEMENT_BEHAVIOR_MERGE}
+ * then cues from multiple instances will be shown on screen simultaneously if their start and
+ * times overlap.
+ *
+ *
{@link C#TIME_UNSET} is only permitted if the {@link Format#cueReplacementBehavior} of the
+ * current track is {@link Format#CUE_REPLACEMENT_BEHAVIOR_REPLACE}.
+ */
+ public final long endTimeUs;
+
/** Creates an instance. */
public CuesWithTiming(List cues, long startTimeUs, long durationUs) {
this.cues = ImmutableList.copyOf(cues);
this.startTimeUs = startTimeUs;
this.durationUs = durationUs;
+ this.endTimeUs =
+ startTimeUs == C.TIME_UNSET || durationUs == C.TIME_UNSET
+ ? C.TIME_UNSET
+ : startTimeUs + durationUs;
}
}
diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/text/CueSerializationTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/text/CueSerializationTest.java
index 95211c08b2..ed7ab221c2 100644
--- a/libraries/extractor/src/test/java/androidx/media3/extractor/text/CueSerializationTest.java
+++ b/libraries/extractor/src/test/java/androidx/media3/extractor/text/CueSerializationTest.java
@@ -67,6 +67,7 @@ public class CueSerializationTest {
assertThat(cuesAfterDecoding.startTimeUs).isEqualTo(1000);
assertThat(cuesAfterDecoding.durationUs).isEqualTo(2000);
+ assertThat(cuesAfterDecoding.endTimeUs).isEqualTo(3000);
Cue cueAfterDecoding = cuesAfterDecoding.cues.get(0);
assertThat(cueAfterDecoding.text.toString()).isEqualTo(cue.text.toString());
@@ -112,6 +113,7 @@ public class CueSerializationTest {
assertThat(cuesAfterDecoding.startTimeUs).isEqualTo(1000);
assertThat(cuesAfterDecoding.durationUs).isEqualTo(2000);
+ assertThat(cuesAfterDecoding.endTimeUs).isEqualTo(3000);
assertThat(cuesAfterDecoding.cues).hasSize(2);
Cue textCueAfterDecoding = cuesAfterDecoding.cues.get(0);