Fix index out of bounds exception when a Subtitle
is empty
Issue: androidx/media#1516 #cherrypick PiperOrigin-RevId: 648416119
This commit is contained in:
parent
70c063905c
commit
711d18de03
@ -24,6 +24,9 @@
|
|||||||
* Audio:
|
* Audio:
|
||||||
* Video:
|
* Video:
|
||||||
* Text:
|
* Text:
|
||||||
|
* Fix an `IllegalArgumentException` from `LegacySubtitleUtil` when a
|
||||||
|
WebVTT subtitle sample contains no cues, e.g. as part of a DASH stream
|
||||||
|
([#1516](https://github.com/androidx/media/issues/1516)).
|
||||||
* Metadata:
|
* Metadata:
|
||||||
* Image:
|
* Image:
|
||||||
* DRM:
|
* DRM:
|
||||||
|
@ -32,11 +32,14 @@ public class LegacySubtitleUtil {
|
|||||||
* Converts a {@link Subtitle} to a list of {@link CuesWithTiming} representing it, emitted to
|
* Converts a {@link Subtitle} to a list of {@link CuesWithTiming} representing it, emitted to
|
||||||
* {@code output}.
|
* {@code output}.
|
||||||
*
|
*
|
||||||
* <p>This may only be called with {@link Subtitle} instances where the first event is non-empty
|
* <p>This may only be called with empty {@link Subtitle} instances, or those where the first
|
||||||
* and the last event is an empty cue list.
|
* event is non-empty and the last event is an empty cue list.
|
||||||
*/
|
*/
|
||||||
public static void toCuesWithTiming(
|
public static void toCuesWithTiming(
|
||||||
Subtitle subtitle, OutputOptions outputOptions, Consumer<CuesWithTiming> output) {
|
Subtitle subtitle, OutputOptions outputOptions, Consumer<CuesWithTiming> output) {
|
||||||
|
if (subtitle.getEventTimeCount() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int startIndex = getStartIndex(subtitle, outputOptions);
|
int startIndex = getStartIndex(subtitle, outputOptions);
|
||||||
boolean startedInMiddleOfCue = false;
|
boolean startedInMiddleOfCue = false;
|
||||||
if (outputOptions.startTimeUs != C.TIME_UNSET) {
|
if (outputOptions.startTimeUs != C.TIME_UNSET) {
|
||||||
|
@ -39,6 +39,8 @@ public class LegacySubtitleUtilWebvttTest {
|
|||||||
private static final String FIRST_SUBTITLE_STRING = "This is the first subtitle.";
|
private static final String FIRST_SUBTITLE_STRING = "This is the first subtitle.";
|
||||||
private static final String SECOND_SUBTITLE_STRING = "This is the second subtitle.";
|
private static final String SECOND_SUBTITLE_STRING = "This is the second subtitle.";
|
||||||
|
|
||||||
|
private static final WebvttSubtitle EMPTY_SUBTITLE = new WebvttSubtitle(ImmutableList.of());
|
||||||
|
|
||||||
private static final WebvttSubtitle SIMPLE_SUBTITLE =
|
private static final WebvttSubtitle SIMPLE_SUBTITLE =
|
||||||
new WebvttSubtitle(
|
new WebvttSubtitle(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
@ -135,6 +137,14 @@ public class LegacySubtitleUtilWebvttTest {
|
|||||||
.containsExactly(SECOND_SUBTITLE_STRING);
|
.containsExactly(SECOND_SUBTITLE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toCuesWithTiming_allCues_emptySubtitle() {
|
||||||
|
ImmutableList<CuesWithTiming> cuesWithTimingsList =
|
||||||
|
toCuesWithTimingList(EMPTY_SUBTITLE, SubtitleParser.OutputOptions.allCues());
|
||||||
|
|
||||||
|
assertThat(cuesWithTimingsList).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void toCuesWithTiming_onlyEmitCuesAfterStartTime_startBetweenCues_simpleSubtitle() {
|
public void toCuesWithTiming_onlyEmitCuesAfterStartTime_startBetweenCues_simpleSubtitle() {
|
||||||
ImmutableList<CuesWithTiming> cuesWithTimingsList =
|
ImmutableList<CuesWithTiming> cuesWithTimingsList =
|
||||||
@ -252,6 +262,14 @@ public class LegacySubtitleUtilWebvttTest {
|
|||||||
.containsExactly(SECOND_SUBTITLE_STRING);
|
.containsExactly(SECOND_SUBTITLE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toCuesWithTiming_onlyEmitCuesAfterStartTime_emptySubtitle() {
|
||||||
|
ImmutableList<CuesWithTiming> cuesWithTimingsList =
|
||||||
|
toCuesWithTimingList(EMPTY_SUBTITLE, SubtitleParser.OutputOptions.onlyCuesAfter(0));
|
||||||
|
|
||||||
|
assertThat(cuesWithTimingsList).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
toCuesWithTiming_emitCuesAfterStartTimeThenThoseBefore_startAtStartOfCue_simpleSubtitle() {
|
toCuesWithTiming_emitCuesAfterStartTimeThenThoseBefore_startAtStartOfCue_simpleSubtitle() {
|
||||||
@ -405,6 +423,14 @@ public class LegacySubtitleUtilWebvttTest {
|
|||||||
.inOrder();
|
.inOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toCuesWithTiming_emitCuesAfterStartTimeThenThoseBefore_emptySubtitle() {
|
||||||
|
ImmutableList<CuesWithTiming> cuesWithTimingsList =
|
||||||
|
toCuesWithTimingList(EMPTY_SUBTITLE, SubtitleParser.OutputOptions.onlyCuesAfter(0));
|
||||||
|
|
||||||
|
assertThat(cuesWithTimingsList).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
private static ImmutableList<CuesWithTiming> toCuesWithTimingList(
|
private static ImmutableList<CuesWithTiming> toCuesWithTimingList(
|
||||||
Subtitle subtitle, SubtitleParser.OutputOptions outputOptions) {
|
Subtitle subtitle, SubtitleParser.OutputOptions outputOptions) {
|
||||||
ImmutableList.Builder<CuesWithTiming> result = ImmutableList.builder();
|
ImmutableList.Builder<CuesWithTiming> result = ImmutableList.builder();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user