From bf77f3b28969942c278ec98a53bcdb6d6b2cb713 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Thu, 13 Aug 2015 20:36:50 +0100 Subject: [PATCH] Simplify subtitle parsing. - Currently all subtitles we parse contain timestamps relative to the sample timestamp, however we add the sample timestamp in inconsistent ways (sometimes in the Subtitle, sometimes in the SubtitleParser). This change converges on a single approach. It also paves the way for passing absolute offsets to use instead, and being able to apply them in a consistent way in a single place (PlayableSubtitle). This functionality will be required for ISO 14496-30 TTML embedded subtitles. Issue: #689 --- .../text/subrip/SubripParserTest.java | 7 +- .../text/webvtt/WebvttParserTest.java | 22 +++--- .../text/webvtt/WebvttSubtitleTest.java | 15 ++-- .../exoplayer/text/PlayableSubtitle.java | 70 +++++++++++++++++++ .../android/exoplayer/text/Subtitle.java | 10 --- .../exoplayer/text/SubtitleParser.java | 4 +- .../exoplayer/text/SubtitleParserHelper.java | 21 +++--- .../exoplayer/text/TextTrackRenderer.java | 6 +- .../exoplayer/text/subrip/SubripParser.java | 9 ++- .../exoplayer/text/subrip/SubripSubtitle.java | 11 +-- .../exoplayer/text/ttml/TtmlParser.java | 7 +- .../exoplayer/text/ttml/TtmlSubtitle.java | 17 ++--- .../exoplayer/text/tx3g/Tx3gParser.java | 5 +- .../exoplayer/text/tx3g/Tx3gSubtitle.java | 17 ++--- .../exoplayer/text/webvtt/WebvttParser.java | 10 +-- .../exoplayer/text/webvtt/WebvttSubtitle.java | 11 +-- 16 files changed, 127 insertions(+), 115 deletions(-) create mode 100644 library/src/main/java/com/google/android/exoplayer/text/PlayableSubtitle.java diff --git a/library/src/androidTest/java/com/google/android/exoplayer/text/subrip/SubripParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer/text/subrip/SubripParserTest.java index 7459442fb2..45a437b78e 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/text/subrip/SubripParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/text/subrip/SubripParserTest.java @@ -34,7 +34,7 @@ public final class SubripParserTest extends InstrumentationTestCase { SubripParser parser = new SubripParser(); InputStream inputStream = getInstrumentation().getContext().getResources().getAssets().open(EMPTY_SUBRIP_FILE); - SubripSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME, 0); + SubripSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME); // Assert that the subtitle is empty. assertEquals(0, subtitle.getEventTimeCount()); assertTrue(subtitle.getCues(0).isEmpty()); @@ -44,10 +44,9 @@ public final class SubripParserTest extends InstrumentationTestCase { SubripParser parser = new SubripParser(); InputStream inputStream = getInstrumentation().getContext().getResources().getAssets().open(TYPICAL_SUBRIP_FILE); - SubripSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME, 0); + SubripSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME); - // Test start time and event count. - assertEquals(0, subtitle.getStartTime()); + // Test event count. assertEquals(4, subtitle.getEventTimeCount()); // Test first cue. diff --git a/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttParserTest.java index f8e8daf43d..3f11474615 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttParserTest.java @@ -39,7 +39,7 @@ public class WebvttParserTest extends InstrumentationTestCase { getInstrumentation().getContext().getResources().getAssets().open(EMPTY_WEBVTT_FILE); try { - parser.parse(inputStream, C.UTF8_NAME, 0); + parser.parse(inputStream, C.UTF8_NAME); fail("Expected IOException"); } catch (IOException expected) { // Do nothing. @@ -50,10 +50,9 @@ public class WebvttParserTest extends InstrumentationTestCase { WebvttParser parser = new WebvttParser(); InputStream inputStream = getInstrumentation().getContext().getResources().getAssets().open(TYPICAL_WEBVTT_FILE); - WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME, 0); + WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME); - // test start time and event count - assertEquals(0, subtitle.getStartTime()); + // test event count assertEquals(4, subtitle.getEventTimeCount()); // test first cue @@ -74,10 +73,9 @@ public class WebvttParserTest extends InstrumentationTestCase { InputStream inputStream = getInstrumentation().getContext().getResources().getAssets() .open(TYPICAL_WITH_IDS_WEBVTT_FILE); - WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME, 0); + WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME); - // test start time and event count - assertEquals(0, subtitle.getStartTime()); + // test event count assertEquals(4, subtitle.getEventTimeCount()); // test first cue @@ -98,10 +96,9 @@ public class WebvttParserTest extends InstrumentationTestCase { InputStream inputStream = getInstrumentation().getContext().getResources().getAssets() .open(TYPICAL_WITH_TAGS_WEBVTT_FILE); - WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME, 0); + WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME); - // test start time and event count - assertEquals(0, subtitle.getStartTime()); + // test event count assertEquals(8, subtitle.getEventTimeCount()); // test first cue @@ -133,11 +130,10 @@ public class WebvttParserTest extends InstrumentationTestCase { WebvttParser parser = new WebvttParser(); InputStream inputStream = getInstrumentation().getContext().getResources().getAssets().open(LIVE_TYPICAL_WEBVTT_FILE); - WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME, 0); + WebvttSubtitle subtitle = parser.parse(inputStream, C.UTF8_NAME); - // test start time and event count + // test event count long startTimeUs = 0; - assertEquals(startTimeUs, subtitle.getStartTime()); assertEquals(4, subtitle.getEventTimeCount()); // test first cue diff --git a/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitleTest.java b/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitleTest.java index e8ce0b387c..675c84dd8a 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitleTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitleTest.java @@ -32,7 +32,7 @@ public class WebvttSubtitleTest extends TestCase { private static final String FIRST_AND_SECOND_SUBTITLE_STRING = FIRST_SUBTITLE_STRING + "\n" + SECOND_SUBTITLE_STRING; - private WebvttSubtitle emptySubtitle = new WebvttSubtitle(new ArrayList(), 0); + private WebvttSubtitle emptySubtitle = new WebvttSubtitle(new ArrayList()); private ArrayList simpleSubtitleCues = new ArrayList<>(); { @@ -42,7 +42,7 @@ public class WebvttSubtitleTest extends TestCase { WebvttCue secondCue = new WebvttCue(3000000, 4000000, SECOND_SUBTITLE_STRING); simpleSubtitleCues.add(secondCue); } - private WebvttSubtitle simpleSubtitle = new WebvttSubtitle(simpleSubtitleCues, 0); + private WebvttSubtitle simpleSubtitle = new WebvttSubtitle(simpleSubtitleCues); private ArrayList overlappingSubtitleCues = new ArrayList<>(); { @@ -52,7 +52,7 @@ public class WebvttSubtitleTest extends TestCase { WebvttCue secondCue = new WebvttCue(2000000, 4000000, SECOND_SUBTITLE_STRING); overlappingSubtitleCues.add(secondCue); } - private WebvttSubtitle overlappingSubtitle = new WebvttSubtitle(overlappingSubtitleCues, 0); + private WebvttSubtitle overlappingSubtitle = new WebvttSubtitle(overlappingSubtitleCues); private ArrayList nestedSubtitleCues = new ArrayList<>(); { @@ -62,7 +62,7 @@ public class WebvttSubtitleTest extends TestCase { WebvttCue secondCue = new WebvttCue(2000000, 3000000, SECOND_SUBTITLE_STRING); nestedSubtitleCues.add(secondCue); } - private WebvttSubtitle nestedSubtitle = new WebvttSubtitle(nestedSubtitleCues, 0); + private WebvttSubtitle nestedSubtitle = new WebvttSubtitle(nestedSubtitleCues); public void testEventCount() { assertEquals(0, emptySubtitle.getEventTimeCount()); @@ -71,13 +71,6 @@ public class WebvttSubtitleTest extends TestCase { assertEquals(4, nestedSubtitle.getEventTimeCount()); } - public void testStartTime() { - assertEquals(0, emptySubtitle.getStartTime()); - assertEquals(0, simpleSubtitle.getStartTime()); - assertEquals(0, overlappingSubtitle.getStartTime()); - assertEquals(0, nestedSubtitle.getStartTime()); - } - public void testLastEventTime() { assertEquals(-1, emptySubtitle.getLastEventTime()); assertEquals(4000000, simpleSubtitle.getLastEventTime()); diff --git a/library/src/main/java/com/google/android/exoplayer/text/PlayableSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/PlayableSubtitle.java new file mode 100644 index 0000000000..6c899387fc --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/text/PlayableSubtitle.java @@ -0,0 +1,70 @@ +package com.google.android.exoplayer.text; + +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.util.List; + +/** + * A subtitle that wraps another subtitle, making it playable by adjusting it to be correctly + * aligned with the playback timebase. + */ +/* package */ final class PlayableSubtitle implements Subtitle { + + /** + * The start time of the subtitle. + *

+ * May be less than {@code getEventTime(0)}, since a subtitle may begin prior to the time of the + * first event. + */ + public final long startTimeUs; + + private final Subtitle subtitle; + + /** + * @param startTimeUs The start time of the subtitle. + * @param subtitle The subtitle to wrap. + */ + public PlayableSubtitle(long startTimeUs, Subtitle subtitle) { + this.startTimeUs = startTimeUs; + this.subtitle = subtitle; + } + + @Override + public int getNextEventTimeIndex(long timeUs) { + return subtitle.getNextEventTimeIndex(timeUs - startTimeUs); + } + + @Override + public int getEventTimeCount() { + return subtitle.getEventTimeCount(); + } + + @Override + public long getEventTime(int index) { + return subtitle.getEventTime(index) + startTimeUs; + } + + @Override + public long getLastEventTime() { + return subtitle.getLastEventTime() + startTimeUs; + } + + @Override + public List getCues(long timeUs) { + return subtitle.getCues(timeUs - startTimeUs); + } + +} diff --git a/library/src/main/java/com/google/android/exoplayer/text/Subtitle.java b/library/src/main/java/com/google/android/exoplayer/text/Subtitle.java index 2b2e1ad44b..55a99cdf43 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/Subtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/Subtitle.java @@ -22,16 +22,6 @@ import java.util.List; */ public interface Subtitle { - /** - * Gets the start time of the subtitle. - *

- * Note that the value returned may be less than {@code getEventTime(0)}, since a subtitle may - * begin prior to the time of the first event. - * - * @return The start time of the subtitle in microseconds. - */ - public long getStartTime(); - /** * Gets the index of the first event that occurs after a given time (exclusive). * diff --git a/library/src/main/java/com/google/android/exoplayer/text/SubtitleParser.java b/library/src/main/java/com/google/android/exoplayer/text/SubtitleParser.java index e041373d6e..f002e457f2 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/SubtitleParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/SubtitleParser.java @@ -36,11 +36,9 @@ public interface SubtitleParser { * * @param inputStream The stream from which to parse the subtitle. * @param inputEncoding The encoding of the input stream. - * @param startTimeUs The start time of the subtitle. * @return A parsed representation of the subtitle. * @throws IOException If a problem occurred reading from the stream. */ - public Subtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) - throws IOException; + public Subtitle parse(InputStream inputStream, String inputEncoding) throws IOException; } diff --git a/library/src/main/java/com/google/android/exoplayer/text/SubtitleParserHelper.java b/library/src/main/java/com/google/android/exoplayer/text/SubtitleParserHelper.java index 835f66aa51..dcd92811e9 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/SubtitleParserHelper.java +++ b/library/src/main/java/com/google/android/exoplayer/text/SubtitleParserHelper.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer.text; import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.util.Assertions; +import com.google.android.exoplayer.util.Util; import android.media.MediaCodec; import android.os.Handler; @@ -31,14 +32,14 @@ import java.io.InputStream; * Wraps a {@link SubtitleParser}, exposing an interface similar to {@link MediaCodec} for * asynchronous parsing of subtitles. */ -public final class SubtitleParserHelper implements Handler.Callback { +/* package */ final class SubtitleParserHelper implements Handler.Callback { private final SubtitleParser parser; private final Handler handler; private SampleHolder sampleHolder; private boolean parsing; - private Subtitle result; + private PlayableSubtitle result; private IOException error; /** @@ -94,7 +95,8 @@ public final class SubtitleParserHelper implements Handler.Callback { parsing = true; result = null; error = null; - handler.obtainMessage(0, sampleHolder).sendToTarget(); + handler.obtainMessage(0, Util.getTopInt(sampleHolder.timeUs), + Util.getBottomInt(sampleHolder.timeUs), sampleHolder).sendToTarget(); } /** @@ -106,7 +108,7 @@ public final class SubtitleParserHelper implements Handler.Callback { * @return The result of the parsing operation, or null. * @throws IOException If the parsing operation failed. */ - public synchronized Subtitle getAndClearResult() throws IOException { + public synchronized PlayableSubtitle getAndClearResult() throws IOException { try { if (error != null) { throw error; @@ -120,22 +122,21 @@ public final class SubtitleParserHelper implements Handler.Callback { @Override public boolean handleMessage(Message msg) { - Subtitle result; - IOException error; + long sampleTimeUs = Util.getLong(msg.arg1, msg.arg2); SampleHolder holder = (SampleHolder) msg.obj; + Subtitle parsedSubtitle = null; + IOException error = null; try { InputStream inputStream = new ByteArrayInputStream(holder.data.array(), 0, holder.size); - result = parser.parse(inputStream, null, sampleHolder.timeUs); - error = null; + parsedSubtitle = parser.parse(inputStream, null); } catch (IOException e) { - result = null; error = e; } synchronized (this) { if (sampleHolder != holder) { // A flush has occurred since this holder was posted. Do nothing. } else { - this.result = result; + this.result = new PlayableSubtitle(sampleTimeUs, parsedSubtitle); this.error = error; this.parsing = false; } diff --git a/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java index d7f8bd9e69..674df03593 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/text/TextTrackRenderer.java @@ -110,8 +110,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement private int parserIndex; private boolean inputStreamEnded; - private Subtitle subtitle; - private Subtitle nextSubtitle; + private PlayableSubtitle subtitle; + private PlayableSubtitle nextSubtitle; private SubtitleParserHelper parserHelper; private HandlerThread parserThread; private int nextSubtitleEventIndex; @@ -208,7 +208,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement } if (subtitleNextEventTimeUs == Long.MAX_VALUE && nextSubtitle != null - && nextSubtitle.getStartTime() <= positionUs) { + && nextSubtitle.startTimeUs <= positionUs) { // Advance to the next subtitle. Sync the next event index and trigger an update. subtitle = nextSubtitle; nextSubtitle = null; diff --git a/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripParser.java b/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripParser.java index bfd04df251..a4a5bf1171 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripParser.java @@ -50,8 +50,7 @@ public final class SubripParser implements SubtitleParser { } @Override - public SubripSubtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) - throws IOException { + public SubripSubtitle parse(InputStream inputStream, String inputEncoding) throws IOException { ArrayList cues = new ArrayList<>(); LongArray cueTimesUs = new LongArray(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, C.UTF8_NAME)); @@ -69,8 +68,8 @@ public final class SubripParser implements SubtitleParser { currentLine = reader.readLine(); Matcher matcher = SUBRIP_TIMING_LINE.matcher(currentLine); if (matcher.find()) { - cueTimesUs.add(startTimeUs + parseTimestampUs(matcher.group(1))); - cueTimesUs.add(startTimeUs + parseTimestampUs(matcher.group(2))); + cueTimesUs.add(parseTimestampUs(matcher.group(1))); + cueTimesUs.add(parseTimestampUs(matcher.group(2))); } else { throw new ParserException("Expected timing line: " + currentLine); } @@ -91,7 +90,7 @@ public final class SubripParser implements SubtitleParser { Cue[] cuesArray = new Cue[cues.size()]; cues.toArray(cuesArray); long[] cueTimesUsArray = cueTimesUs.toArray(); - return new SubripSubtitle(startTimeUs, cuesArray, cueTimesUsArray); + return new SubripSubtitle(cuesArray, cueTimesUsArray); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripSubtitle.java index 9931a1490f..497628f88e 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripSubtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/subrip/SubripSubtitle.java @@ -28,27 +28,18 @@ import java.util.List; */ /* package */ final class SubripSubtitle implements Subtitle { - private final long startTimeUs; - private final Cue[] cues; private final long[] cueTimesUs; /** - * @param startTimeUs The start time of the subtitle, in microseconds. * @param cues The cues in the subtitle. * @param cueTimesUs Interleaved cue start and end times, in microseconds. */ - public SubripSubtitle(long startTimeUs, Cue[] cues, long[] cueTimesUs) { - this.startTimeUs = startTimeUs; + public SubripSubtitle(Cue[] cues, long[] cueTimesUs) { this.cues = cues; this.cueTimesUs = cueTimesUs; } - @Override - public long getStartTime() { - return startTimeUs; - } - @Override public int getNextEventTimeIndex(long timeUs) { int index = Util.binarySearchCeil(cueTimesUs, timeUs, false, false); diff --git a/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlParser.java b/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlParser.java index 22bc7e1975..7c0c2da55a 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlParser.java @@ -84,7 +84,7 @@ public final class TtmlParser implements SubtitleParser { } /** - * @param strictParsing If true, {@link #parse(InputStream, String, long)} will throw a + * @param strictParsing If true, {@link #parse(InputStream, String)} will throw a * {@link ParserException} if the stream contains invalid data. If false, the parser will * make a best effort to ignore minor errors in the stream. Note however that a * {@link ParserException} will still be thrown when this is not possible. @@ -99,8 +99,7 @@ public final class TtmlParser implements SubtitleParser { } @Override - public Subtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) - throws IOException { + public Subtitle parse(InputStream inputStream, String inputEncoding) throws IOException { try { XmlPullParser xmlParser = xmlParserFactory.newPullParser(); xmlParser.setInput(inputStream, inputEncoding); @@ -137,7 +136,7 @@ public final class TtmlParser implements SubtitleParser { parent.addChild(TtmlNode.buildTextNode(xmlParser.getText())); } else if (eventType == XmlPullParser.END_TAG) { if (xmlParser.getName().equals(TtmlNode.TAG_TT)) { - ttmlSubtitle = new TtmlSubtitle(nodeStack.getLast(), startTimeUs); + ttmlSubtitle = new TtmlSubtitle(nodeStack.getLast()); } nodeStack.removeLast(); } diff --git a/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlSubtitle.java index cfcd657082..4029b0ae24 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlSubtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlSubtitle.java @@ -28,23 +28,16 @@ import java.util.List; public final class TtmlSubtitle implements Subtitle { private final TtmlNode root; - private final long startTimeUs; private final long[] eventTimesUs; - public TtmlSubtitle(TtmlNode root, long startTimeUs) { + public TtmlSubtitle(TtmlNode root) { this.root = root; - this.startTimeUs = startTimeUs; this.eventTimesUs = root.getEventTimesUs(); } - @Override - public long getStartTime() { - return startTimeUs; - } - @Override public int getNextEventTimeIndex(long timeUs) { - int index = Util.binarySearchCeil(eventTimesUs, timeUs - startTimeUs, false, false); + int index = Util.binarySearchCeil(eventTimesUs, timeUs, false, false); return index < eventTimesUs.length ? index : -1; } @@ -55,17 +48,17 @@ public final class TtmlSubtitle implements Subtitle { @Override public long getEventTime(int index) { - return eventTimesUs[index] + startTimeUs; + return eventTimesUs[index]; } @Override public long getLastEventTime() { - return (eventTimesUs.length == 0 ? -1 : eventTimesUs[eventTimesUs.length - 1]) + startTimeUs; + return (eventTimesUs.length == 0 ? -1 : eventTimesUs[eventTimesUs.length - 1]); } @Override public List getCues(long timeUs) { - CharSequence cueText = root.getText(timeUs - startTimeUs); + CharSequence cueText = root.getText(timeUs); if (cueText == null) { return Collections.emptyList(); } else { diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gParser.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gParser.java index 2d4d04079b..4a370be3ca 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gParser.java @@ -32,11 +32,10 @@ import java.io.InputStream; public final class Tx3gParser implements SubtitleParser { @Override - public Subtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) - throws IOException { + public Subtitle parse(InputStream inputStream, String inputEncoding) throws IOException { DataInputStream dataInputStream = new DataInputStream(inputStream); String cueText = dataInputStream.readUTF(); - return new Tx3gSubtitle(startTimeUs, new Cue(cueText)); + return new Tx3gSubtitle(new Cue(cueText)); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gSubtitle.java index dfcaf98863..d3ff90fcda 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gSubtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/Tx3gSubtitle.java @@ -27,22 +27,15 @@ import java.util.List; */ /* package */ final class Tx3gSubtitle implements Subtitle { - private final long startTimeUs; private final List cues; - public Tx3gSubtitle(long startTimeUs, Cue cue) { - this.startTimeUs = startTimeUs; + public Tx3gSubtitle(Cue cue) { this.cues = Collections.singletonList(cue); } - @Override - public long getStartTime() { - return startTimeUs; - } - @Override public int getNextEventTimeIndex(long timeUs) { - return timeUs < startTimeUs ? 0 : -1; + return timeUs < 0 ? 0 : -1; } @Override @@ -53,17 +46,17 @@ import java.util.List; @Override public long getEventTime(int index) { Assertions.checkArgument(index == 0); - return startTimeUs; + return 0; } @Override public long getLastEventTime() { - return startTimeUs; + return 0; } @Override public List getCues(long timeUs) { - return timeUs >= startTimeUs ? cues : Collections.emptyList(); + return timeUs >= 0 ? cues : Collections.emptyList(); } } diff --git a/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java b/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java index 091f8150f6..78bfb5abf7 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java @@ -74,7 +74,7 @@ public final class WebvttParser implements SubtitleParser { } /** - * @param strictParsing If true, {@link #parse(InputStream, String, long)} will throw a + * @param strictParsing If true, {@link #parse(InputStream, String)} will throw a * {@link ParserException} if the stream contains invalid data. If false, the parser will * make a best effort to ignore minor errors in the stream. Note however that a * {@link ParserException} will still be thrown when this is not possible. @@ -85,7 +85,7 @@ public final class WebvttParser implements SubtitleParser { } @Override - public final WebvttSubtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) + public final WebvttSubtitle parse(InputStream inputStream, String inputEncoding) throws IOException { ArrayList subtitles = new ArrayList<>(); @@ -142,7 +142,7 @@ public final class WebvttParser implements SubtitleParser { if (!matcher.find()) { throw new ParserException("Expected cue start time: " + line); } else { - startTime = parseTimestampUs(matcher.group()) + startTimeUs; + startTime = parseTimestampUs(matcher.group()); } // parse end timestamp @@ -151,7 +151,7 @@ public final class WebvttParser implements SubtitleParser { throw new ParserException("Expected cue end time: " + line); } else { endTimeString = matcher.group(); - endTime = parseTimestampUs(endTimeString) + startTimeUs; + endTime = parseTimestampUs(endTimeString); } // parse the (optional) cue setting list @@ -213,7 +213,7 @@ public final class WebvttParser implements SubtitleParser { subtitles.add(cue); } - return new WebvttSubtitle(subtitles, startTimeUs); + return new WebvttSubtitle(subtitles); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitle.java index 3cc7ba6362..1f78a82a7e 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttSubtitle.java @@ -34,18 +34,14 @@ public final class WebvttSubtitle implements Subtitle { private final List cues; private final int numCues; - private final long startTimeUs; private final long[] cueTimesUs; private final long[] sortedCueTimesUs; /** * @param cues A list of the cues in this subtitle. - * @param startTimeUs The start time of the subtitle. */ - public WebvttSubtitle(List cues, long startTimeUs) { + public WebvttSubtitle(List cues) { this.cues = cues; - this.startTimeUs = startTimeUs; - numCues = cues.size(); cueTimesUs = new long[2 * numCues]; for (int cueIndex = 0; cueIndex < numCues; cueIndex++) { @@ -58,11 +54,6 @@ public final class WebvttSubtitle implements Subtitle { Arrays.sort(sortedCueTimesUs); } - @Override - public long getStartTime() { - return startTimeUs; - } - @Override public int getNextEventTimeIndex(long timeUs) { Assertions.checkArgument(timeUs >= 0);