mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Make milliseconds optional in SubRip (SRT) subtitles
issue:#7122 PiperOrigin-RevId: 303154493
This commit is contained in:
parent
47d5dd911c
commit
2842eb3eb4
@ -86,7 +86,7 @@
|
|||||||
([#6885](https://github.com/google/ExoPlayer/issues/6885)).
|
([#6885](https://github.com/google/ExoPlayer/issues/6885)).
|
||||||
* Parse `tts:ruby` and `tts:rubyPosition` properties in TTML subtitles
|
* Parse `tts:ruby` and `tts:rubyPosition` properties in TTML subtitles
|
||||||
(rendering is coming later).
|
(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)).
|
([#7122](https://github.com/google/ExoPlayer/issues/7122)).
|
||||||
* DRM:
|
* DRM:
|
||||||
* Add support for attaching DRM sessions to clear content in the demo app.
|
* Add support for attaching DRM sessions to clear content in the demo app.
|
||||||
|
@ -41,8 +41,8 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
|
|||||||
|
|
||||||
private static final String TAG = "SubripDecoder";
|
private static final String TAG = "SubripDecoder";
|
||||||
|
|
||||||
// Some SRT files don't include hours in the timecode, so we use an optional group.
|
// 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 String SUBRIP_TIMECODE = "(?:(\\d+):)?(\\d+):(\\d+)(?:,(\\d+))?";
|
||||||
private static final Pattern SUBRIP_TIMING_LINE =
|
private static final Pattern SUBRIP_TIMING_LINE =
|
||||||
Pattern.compile("\\s*(" + SUBRIP_TIMECODE + ")\\s*-->\\s*(" + SUBRIP_TIMECODE + ")\\s*");
|
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;
|
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 + 2)) * 60 * 1000;
|
||||||
timestampMs += Long.parseLong(matcher.group(groupOffset + 3)) * 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;
|
return timestampMs * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public final class SubripDecoderTest {
|
|||||||
private static final String TYPICAL_NEGATIVE_TIMESTAMPS = "subrip/typical_negative_timestamps";
|
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_UNEXPECTED_END = "subrip/typical_unexpected_end";
|
||||||
private static final String TYPICAL_WITH_TAGS = "subrip/typical_with_tags";
|
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
|
@Test
|
||||||
public void decodeEmpty() throws IOException {
|
public void decodeEmpty() throws IOException {
|
||||||
@ -179,15 +179,17 @@ public final class SubripDecoderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void decodeTypicalNoHours() throws IOException {
|
public void decodeTypicalNoHoursAndMillis() throws IOException {
|
||||||
SubripDecoder decoder = new SubripDecoder();
|
SubripDecoder decoder = new SubripDecoder();
|
||||||
byte[] bytes =
|
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);
|
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
|
||||||
|
|
||||||
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
|
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
|
||||||
assertTypicalCue1(subtitle, 0);
|
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);
|
assertTypicalCue3(subtitle, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
This is the first subtitle.
|
This is the first subtitle.
|
||||||
|
|
||||||
2
|
2
|
||||||
00:02,345 --> 00:03,456
|
00:00:02 --> 00:00:03
|
||||||
This is the second subtitle.
|
This is the second subtitle.
|
||||||
Second subtitle with second line.
|
Second subtitle with second line.
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user