Commit 4347bf04 by Oliver Woodman

Subrip cleanup

parent 4d6b008e
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* Fix issue where subtitles have a wrong position if SubtitleView has a non-zero * Fix issue where subtitles have a wrong position if SubtitleView has a non-zero
offset to its parent offset to its parent
([#4788](https://github.com/google/ExoPlayer/issues/4788)). ([#4788](https://github.com/google/ExoPlayer/issues/4788)).
* SubRip: Add support for alignment tags, and remove tags from the displayed
captions ([#4306](https://github.com/google/ExoPlayer/issues/4306)).
### 2.9.0 ### ### 2.9.0 ###
......
...@@ -13,7 +13,7 @@ This {\an2} is the third {\ tag} subtitle. ...@@ -13,7 +13,7 @@ This {\an2} is the third {\ tag} subtitle.
4 4
00:00:09,567 --> 00:00:12,901 00:00:09,567 --> 00:00:12,901
This { \an2} is the fourth subtitle. This { \an2} is not a valid tag due to the space after the opening bracket.
5 5
00:00:013,567 --> 00:00:14,901 00:00:013,567 --> 00:00:14,901
...@@ -53,4 +53,4 @@ This {\an8} is a line. ...@@ -53,4 +53,4 @@ This {\an8} is a line.
14 14
00:00:024,567 --> 00:00:24,901 00:00:024,567 --> 00:00:24,901
This {\an9} is a line. This {\an9} is a line.
\ No newline at end of file
...@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; ...@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import java.io.IOException; import java.io.IOException;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -158,89 +157,30 @@ public final class SubripDecoderTest { ...@@ -158,89 +157,30 @@ public final class SubripDecoderTest {
} }
@Test @Test
public void testDecodeCueWithTag() throws IOException{ public void testDecodeCueWithTag() throws IOException {
SubripDecoder decoder = new SubripDecoder(); SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_WITH_TAGS); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_WITH_TAGS);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false); SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getCues(subtitle.getEventTime(0)).get(0).text.toString())
.isEqualTo("This is the first subtitle.");
assertThat(subtitle.getCues(subtitle.getEventTime(2)).get(0).text.toString())
.isEqualTo("This is the second subtitle.\nSecond subtitle with second line.");
assertThat(subtitle.getCues(subtitle.getEventTime(4)).get(0).text.toString())
.isEqualTo("This is the third subtitle.");
// Based on the SSA v4+ specs the curly bracket must be followed by a backslash, so this is assertTypicalCue1(subtitle, 0);
// not a valid tag (won't be parsed / replaced) assertTypicalCue2(subtitle, 2);
assertTypicalCue3(subtitle, 4);
assertThat(subtitle.getCues(subtitle.getEventTime(6)).get(0).text.toString()) assertThat(subtitle.getCues(subtitle.getEventTime(6)).get(0).text.toString())
.isEqualTo("This { \\an2} is the fourth subtitle."); .isEqualTo("This { \\an2} is not a valid tag due to the space after the opening bracket.");
assertThat(subtitle.getCues(subtitle.getEventTime(8)).get(0).text.toString()) assertThat(subtitle.getCues(subtitle.getEventTime(8)).get(0).text.toString())
.isEqualTo("This is the fifth subtitle with multiple valid tags."); .isEqualTo("This is the fifth subtitle with multiple valid tags.");
// Verify positions assertAlignmentCue(subtitle, 10, Cue.ANCHOR_TYPE_END, Cue.ANCHOR_TYPE_START); // {/an1}
assertAlignmentCue(subtitle, 12, Cue.ANCHOR_TYPE_END, Cue.ANCHOR_TYPE_MIDDLE); // {/an2}
// {/an1} assertAlignmentCue(subtitle, 14, Cue.ANCHOR_TYPE_END, Cue.ANCHOR_TYPE_END); // {/an3}
assertThat(subtitle.getCues(subtitle.getEventTime(10)).get(0).positionAnchor) assertAlignmentCue(subtitle, 16, Cue.ANCHOR_TYPE_MIDDLE, Cue.ANCHOR_TYPE_START); // {/an4}
.isEqualTo(Cue.ANCHOR_TYPE_START); assertAlignmentCue(subtitle, 18, Cue.ANCHOR_TYPE_MIDDLE, Cue.ANCHOR_TYPE_MIDDLE); // {/an5}
assertAlignmentCue(subtitle, 20, Cue.ANCHOR_TYPE_MIDDLE, Cue.ANCHOR_TYPE_END); // {/an6}
assertThat(subtitle.getCues(subtitle.getEventTime(10)).get(0).lineAnchor) assertAlignmentCue(subtitle, 22, Cue.ANCHOR_TYPE_START, Cue.ANCHOR_TYPE_START); // {/an7}
.isEqualTo(Cue.ANCHOR_TYPE_END); assertAlignmentCue(subtitle, 24, Cue.ANCHOR_TYPE_START, Cue.ANCHOR_TYPE_MIDDLE); // {/an8}
assertAlignmentCue(subtitle, 26, Cue.ANCHOR_TYPE_START, Cue.ANCHOR_TYPE_END); // {/an9}
// {/an2}
assertThat(subtitle.getCues(subtitle.getEventTime(12)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_MIDDLE);
assertThat(subtitle.getCues(subtitle.getEventTime(12)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_END);
// {/an3}
assertThat(subtitle.getCues(subtitle.getEventTime(14)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_END);
assertThat(subtitle.getCues(subtitle.getEventTime(14)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_END);
// {/an4}
assertThat(subtitle.getCues(subtitle.getEventTime(16)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_START);
assertThat(subtitle.getCues(subtitle.getEventTime(16)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_MIDDLE);
// {/an5}
assertThat(subtitle.getCues(subtitle.getEventTime(18)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_MIDDLE);
assertThat(subtitle.getCues(subtitle.getEventTime(18)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_MIDDLE);
// {/an6}
assertThat(subtitle.getCues(subtitle.getEventTime(20)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_END);
assertThat(subtitle.getCues(subtitle.getEventTime(20)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_MIDDLE);
// {/an7}
assertThat(subtitle.getCues(subtitle.getEventTime(22)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_START);
assertThat(subtitle.getCues(subtitle.getEventTime(22)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_START);
// {/an8}
assertThat(subtitle.getCues(subtitle.getEventTime(24)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_MIDDLE);
assertThat(subtitle.getCues(subtitle.getEventTime(24)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_START);
// {/an9}
assertThat(subtitle.getCues(subtitle.getEventTime(26)).get(0).positionAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_END);
assertThat(subtitle.getCues(subtitle.getEventTime(26)).get(0).lineAnchor)
.isEqualTo(Cue.ANCHOR_TYPE_START);
} }
private static void assertTypicalCue1(SubripSubtitle subtitle, int eventIndex) { private static void assertTypicalCue1(SubripSubtitle subtitle, int eventIndex) {
...@@ -263,4 +203,19 @@ public final class SubripDecoderTest { ...@@ -263,4 +203,19 @@ public final class SubripDecoderTest {
.isEqualTo("This is the third subtitle."); .isEqualTo("This is the third subtitle.");
assertThat(subtitle.getEventTime(eventIndex + 1)).isEqualTo(8901000); assertThat(subtitle.getEventTime(eventIndex + 1)).isEqualTo(8901000);
} }
private static void assertAlignmentCue(
SubripSubtitle subtitle,
int eventIndex,
@Cue.AnchorType int lineAnchor,
@Cue.AnchorType int positionAnchor) {
long eventTimeUs = subtitle.getEventTime(eventIndex);
Cue cue = subtitle.getCues(eventTimeUs).get(0);
assertThat(cue.lineType).isEqualTo(Cue.LINE_TYPE_FRACTION);
assertThat(cue.lineAnchor).isEqualTo(lineAnchor);
assertThat(cue.line).isEqualTo(SubripDecoder.getFractionalPositionForAnchorType(lineAnchor));
assertThat(cue.positionAnchor).isEqualTo(positionAnchor);
assertThat(cue.position)
.isEqualTo(SubripDecoder.getFractionalPositionForAnchorType(positionAnchor));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment