diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f2e9c8f3ed..6e5a4b5c59 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -86,7 +86,7 @@ ([#6885](https://github.com/google/ExoPlayer/issues/6885)). * Parse `tts:ruby` and `tts:rubyPosition` properties in TTML subtitles (rendering is coming later). - * Allow missing hours in SubRip (.srt) timecodes + * Allow missing hours & milliseconds in SubRip (.srt) timecodes ([#7122](https://github.com/google/ExoPlayer/issues/7122)). * DRM: * Add support for attaching DRM sessions to clear content in the demo app. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java index 2b562ff8c7..cef7e3f53f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java @@ -41,8 +41,8 @@ public final class SubripDecoder extends SimpleSubtitleDecoder { private static final String TAG = "SubripDecoder"; - // Some SRT files don't include hours in the timecode, so we use an optional group. - private static final String SUBRIP_TIMECODE = "(?:(\\d+):)?(\\d+):(\\d+),(\\d+)"; + // Some SRT files don't include hours or milliseconds in the timecode, so we use optional groups. + private static final String SUBRIP_TIMECODE = "(?:(\\d+):)?(\\d+):(\\d+)(?:,(\\d+))?"; private static final Pattern SUBRIP_TIMING_LINE = Pattern.compile("\\s*(" + SUBRIP_TIMECODE + ")\\s*-->\\s*(" + SUBRIP_TIMECODE + ")\\s*"); @@ -235,7 +235,10 @@ public final class SubripDecoder extends SimpleSubtitleDecoder { long timestampMs = hours != null ? Long.parseLong(hours) * 60 * 60 * 1000 : 0; timestampMs += Long.parseLong(matcher.group(groupOffset + 2)) * 60 * 1000; timestampMs += Long.parseLong(matcher.group(groupOffset + 3)) * 1000; - timestampMs += Long.parseLong(matcher.group(groupOffset + 4)); + @Nullable String millis = matcher.group(groupOffset + 4); + if (millis != null) { + timestampMs += Long.parseLong(millis); + } return timestampMs * 1000; } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java b/library/core/src/test/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java index 2648875de0..e233d8d1b5 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java @@ -39,7 +39,7 @@ public final class SubripDecoderTest { private static final String TYPICAL_NEGATIVE_TIMESTAMPS = "subrip/typical_negative_timestamps"; private static final String TYPICAL_UNEXPECTED_END = "subrip/typical_unexpected_end"; private static final String TYPICAL_WITH_TAGS = "subrip/typical_with_tags"; - private static final String TYPICAL_NO_HOURS = "subrip/typical_no_hours"; + private static final String TYPICAL_NO_HOURS_AND_MILLIS = "subrip/typical_no_hours_and_millis"; @Test public void decodeEmpty() throws IOException { @@ -179,15 +179,17 @@ public final class SubripDecoderTest { } @Test - public void decodeTypicalNoHours() throws IOException { + public void decodeTypicalNoHoursAndMillis() throws IOException { SubripDecoder decoder = new SubripDecoder(); byte[] bytes = - TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), TYPICAL_NO_HOURS); + TestUtil.getByteArray( + ApplicationProvider.getApplicationContext(), TYPICAL_NO_HOURS_AND_MILLIS); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); assertThat(subtitle.getEventTimeCount()).isEqualTo(6); assertTypicalCue1(subtitle, 0); - assertTypicalCue2(subtitle, 2); + assertThat(subtitle.getEventTime(2)).isEqualTo(2_000_000); + assertThat(subtitle.getEventTime(3)).isEqualTo(3_000_000); assertTypicalCue3(subtitle, 4); } diff --git a/testdata/src/test/assets/subrip/typical_no_hours b/testdata/src/test/assets/subrip/typical_no_hours_and_millis similarity index 88% rename from testdata/src/test/assets/subrip/typical_no_hours rename to testdata/src/test/assets/subrip/typical_no_hours_and_millis index c4bf372a3c..5340fc72c2 100644 --- a/testdata/src/test/assets/subrip/typical_no_hours +++ b/testdata/src/test/assets/subrip/typical_no_hours_and_millis @@ -3,7 +3,7 @@ This is the first subtitle. 2 -00:02,345 --> 00:03,456 +00:00:02 --> 00:00:03 This is the second subtitle. Second subtitle with second line.