From f42ed8920215c78ee61df924a06d120a3d1c50b3 Mon Sep 17 00:00:00 2001 From: ood_tsen Date: Mon, 1 Jun 2015 19:47:46 +0800 Subject: [PATCH 1/5] parse mp4 tx3g --- .../demo/player/ExtractorRendererBuilder.java | 5 + .../google/android/exoplayer/MediaFormat.java | 4 + .../android/exoplayer/extractor/mp4/Atom.java | 2 +- .../exoplayer/extractor/mp4/AtomParsers.java | 2 + .../exoplayer/extractor/mp4/Mp4Extractor.java | 6 +- .../exoplayer/text/tx3g/SubtitleData.java | 65 +++++++++++ .../exoplayer/text/tx3g/TextParser.java | 102 ++++++++++++++++++ .../exoplayer/text/tx3g/TextSubtitle.java | 97 +++++++++++++++++ .../android/exoplayer/util/MimeTypes.java | 1 + 9 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java create mode 100644 library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java create mode 100644 library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorRendererBuilder.java index 6cab32227d..c94aa1e24d 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorRendererBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorRendererBuilder.java @@ -22,6 +22,8 @@ import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder; import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback; import com.google.android.exoplayer.extractor.Extractor; import com.google.android.exoplayer.extractor.ExtractorSampleSource; +import com.google.android.exoplayer.text.TextTrackRenderer; +import com.google.android.exoplayer.text.tx3g.TextParser; import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer.upstream.DefaultUriDataSource; @@ -63,10 +65,13 @@ public class ExtractorRendererBuilder implements RendererBuilder { MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, null, true, player.getMainHandler(), player); + TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player, player.getMainHandler().getLooper(), new TextParser()); + // Invoke the callback. TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer; renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer; + renderers[DemoPlayer.TYPE_TEXT] = textRenderer; callback.onRenderers(null, null, renderers, bandwidthMeter); } diff --git a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java index bb266934f4..3bce2d8902 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java @@ -106,6 +106,10 @@ public class MediaFormat { return createFormatForMimeType(MimeTypes.APPLICATION_TTML); } + public static MediaFormat createTx3GFormat() { + return createFormatForMimeType(MimeTypes.TEXT_TX3G); + } + public static MediaFormat createFormatForMimeType(String mimeType) { return new MediaFormat(mimeType, NO_VALUE, C.UNKNOWN_TIME_US, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null); diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Atom.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Atom.java index a2b3524ddb..55378fa9fa 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Atom.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Atom.java @@ -91,7 +91,7 @@ import java.util.List; public static final int TYPE_stsz = Util.getIntegerCodeForString("stsz"); public static final int TYPE_stco = Util.getIntegerCodeForString("stco"); public static final int TYPE_co64 = Util.getIntegerCodeForString("co64"); - + public static final int TYPE_tx3g = Util.getIntegerCodeForString("tx3g"); public final int type; Atom(int type) { diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java index 846c71ad9b..418fb3e855 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java @@ -340,6 +340,8 @@ import java.util.List; holder, i); } else if (childAtomType == Atom.TYPE_TTML) { holder.mediaFormat = MediaFormat.createTtmlFormat(); + } else if (childAtomType == Atom.TYPE_tx3g) { + holder.mediaFormat = MediaFormat.createTx3GFormat(); } stsd.setPosition(childStartPosition + childAtomSize); } diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java index 1c8b2b4faa..ed0241477a 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java @@ -225,7 +225,8 @@ public final class Mp4Extractor implements Extractor, SeekMap { } Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd)); - if (track == null || (track.type != Track.TYPE_AUDIO && track.type != Track.TYPE_VIDEO)) { + if (track == null || (track.type != Track.TYPE_AUDIO && track.type != Track.TYPE_VIDEO && + track.type != Track.TYPE_TEXT)) { continue; } @@ -359,7 +360,8 @@ public final class Mp4Extractor implements Extractor, SeekMap { || atom == Atom.TYPE_avc1 || atom == Atom.TYPE_avcC || atom == Atom.TYPE_mp4a || atom == Atom.TYPE_esds || atom == Atom.TYPE_stts || atom == Atom.TYPE_stss || atom == Atom.TYPE_ctts || atom == Atom.TYPE_stsc || atom == Atom.TYPE_stsz - || atom == Atom.TYPE_stco || atom == Atom.TYPE_co64 || atom == Atom.TYPE_tkhd; + || atom == Atom.TYPE_stco || atom == Atom.TYPE_co64 || atom == Atom.TYPE_tkhd + || atom == Atom.TYPE_tx3g; } /** Returns whether the extractor should parse a container atom with type {@code atom}. */ diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java new file mode 100644 index 0000000000..55fd44f81e --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java @@ -0,0 +1,65 @@ +package com.google.android.exoplayer.text.tx3g; + +import java.util.Comparator; + +class SubtitleData implements Comparable , Comparator { + + private long mStartTimePosUs; + private long mEndTimePosUs; + private String strSubtitle; + + SubtitleData() + { + mStartTimePosUs = 0l; + mEndTimePosUs = 0l; + strSubtitle = ""; + } + + protected void setStartTimePos(long time) + { + mStartTimePosUs = time; + } + + protected void setEndTimePos(long time) + { + mEndTimePosUs = time; + } + + protected void setSubtitleText(String text) + { + strSubtitle = text; + } + + protected long getStartTimePos() + { + return mStartTimePosUs; + } + + protected long getEndTimePos() + { + return mEndTimePosUs; + } + + protected String getsubtitleText() + { + return strSubtitle; + } + + @Override + public int compare(SubtitleData o1 , SubtitleData o2) { + if (o1.getStartTimePos() < o2.getStartTimePos()) + return -1; + if (o1.getStartTimePos() > o2.getStartTimePos()) + return 1; + return 0; + } + + @Override + public int compareTo(SubtitleData another) { + if (getStartTimePos() < another.getStartTimePos()) + return -1; + if (getStartTimePos() > another.getStartTimePos()) + return 1; + return 0; + } +} diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java new file mode 100644 index 0000000000..a802761d6b --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java @@ -0,0 +1,102 @@ +/* + * 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. + */ +package com.google.android.exoplayer.text.tx3g; + +import com.google.android.exoplayer.text.Subtitle; +import com.google.android.exoplayer.text.SubtitleParser; +import com.google.android.exoplayer.util.MimeTypes; + +import android.util.Log; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +/** + * A simple Text parser that supports Tx3g presentation profile. + *

+ * Supported features in this parser are: + *

    + *
  • content + *
  • core + *
  • presentation + *
  • profile + *
  • structure + *
  • time-offset + *
  • timing + *
  • tickRate + *
  • time-clock-with-frames + *
  • time-clock + *
  • time-offset-with-frames + *
  • time-offset-with-ticks + *
+ *

+ * @see TTML specification + */ +public class TextParser implements SubtitleParser { + private static final String TAG = "TextParser"; + + + private final List mSubtitleList; + + /** + * Equivalent to {@code TtmlParser(true)}. + */ + public TextParser() { + Log.i(TAG,"TextParser "); + mSubtitleList = new LinkedList(); + } + + + @Override + public Subtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) + throws IOException { + + DataInputStream in = new DataInputStream(inputStream); + String text = in.readUTF(); + text = (text == null) ? "" : text; + Log.i(TAG,"parse(" + text + "," + startTimeUs + ")" ); + + SubtitleData cue = new SubtitleData(); + cue.setSubtitleText(text); + cue.setStartTimePos(startTimeUs); + mSubtitleList.add(cue); + + Collections.sort(mSubtitleList, new Comparator() { + @Override + public int compare(SubtitleData o1 , SubtitleData o2) { + if (o1.getStartTimePos() < o2.getStartTimePos()) + return -1; + if (o1.getStartTimePos() > o2.getStartTimePos()) + return 1; + return 0; + } + }); + TextSubtitle textSubtitle = new TextSubtitle(mSubtitleList); + return textSubtitle; + } + + @Override + public boolean canParse(String mimeType) { + boolean rtn = MimeTypes.TEXT_TX3G.equals(mimeType); + Log.i(TAG,"canParse " + mimeType + "," + rtn); + return rtn; + } +} diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java new file mode 100644 index 0000000000..32f1a76d24 --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java @@ -0,0 +1,97 @@ +/* + * 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. + */ +package com.google.android.exoplayer.text.tx3g; + +import java.util.ArrayList; +import java.util.List; + +import com.google.android.exoplayer.text.Cue; +import com.google.android.exoplayer.text.Subtitle; + +/** + * A representation of a TTML subtitle. + */ +public final class TextSubtitle implements Subtitle { + static String TAG = "TextSubtitle"; + private final List text; + + public TextSubtitle(List text) { + this.text = text; + } + + @Override + public long getStartTime() { + return text.get(0).getStartTimePos(); + } + + @Override + public int getNextEventTimeIndex(long timeUs) { + + int index = findTheClosed(timeUs); + int next = (index ) < text.size() ? (index ) : -1; + return next; + } + + @Override + public int getEventTimeCount() { + //LOG.I(TAG,"getEventTimeCount() = " + text.size()); + return text.size(); + } + + @Override + public long getEventTime(int index) { + if (index > text.size() - 1) return -1; + + //LOG.I(TAG,"getEventTime(" + index + ") = " + text.get(index).getStartTimePos()); + return text.get(index).getStartTimePos(); + } + + @Override + public long getLastEventTime() { + return text.get(0).getStartTimePos(); + } + + @Override + public List getCues(long timeUs) { + int index = findTheClosed(timeUs); + List list = new ArrayList<>(); + if (index == -1) return null; + + String str = text.get(index).getsubtitleText(); + + list.add(new Cue(str)); + return list; + } + + private int findTheClosed(long timeUs) { + + int length = text.size(); + for (int i = 0; i < length ; i++) { + SubtitleData data = text.get(i); + boolean bCheckFront = data.getStartTimePos() <= timeUs ; + boolean bCheckEnd = false; + if (i + 1 < length) { + bCheckEnd = text.get(i + 1).getStartTimePos() > timeUs ; + } else if (i + 1 == length) { + bCheckEnd = true; + } + + if (bCheckFront && bCheckEnd) + return i; + } + return -1; + } +} diff --git a/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java b/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java index 21aa81a965..dea171b6df 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java +++ b/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java @@ -53,6 +53,7 @@ public class MimeTypes { public static final String AUDIO_OPUS = BASE_TYPE_AUDIO + "/opus"; public static final String TEXT_VTT = BASE_TYPE_TEXT + "/vtt"; + public static final String TEXT_TX3G = BASE_TYPE_TEXT + "/tx3g"; public static final String APPLICATION_ID3 = BASE_TYPE_APPLICATION + "/id3"; public static final String APPLICATION_EIA608 = BASE_TYPE_APPLICATION + "/eia-608"; From 39607551aa222a2d92abb0c501db78ed8eae6dd1 Mon Sep 17 00:00:00 2001 From: ood_tsen Date: Mon, 1 Jun 2015 20:47:55 +0800 Subject: [PATCH 2/5] add title. --- .../exoplayer/text/tx3g/SubtitleData.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java index 55fd44f81e..1bba2de8bd 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java @@ -1,3 +1,19 @@ +/* + * 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. + */ + package com.google.android.exoplayer.text.tx3g; import java.util.Comparator; From 106ebbf7dfd37f5feba24200e6ed3192e7a3e494 Mon Sep 17 00:00:00 2001 From: ood_tsen Date: Tue, 2 Jun 2015 21:00:22 +0800 Subject: [PATCH 3/5] clean up unused code. --- .../google/android/exoplayer/MediaFormat.java | 2 +- .../exoplayer/text/tx3g/SubtitleData.java | 50 ++++--------------- .../exoplayer/text/tx3g/TextParser.java | 50 ++++++------------- .../exoplayer/text/tx3g/TextSubtitle.java | 5 +- .../android/exoplayer/util/MimeTypes.java | 2 +- 5 files changed, 28 insertions(+), 81 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java index 3bce2d8902..aaaad2cf26 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java @@ -107,7 +107,7 @@ public class MediaFormat { } public static MediaFormat createTx3GFormat() { - return createFormatForMimeType(MimeTypes.TEXT_TX3G); + return createFormatForMimeType(MimeTypes.APPLICATION_TX3G); } public static MediaFormat createFormatForMimeType(String mimeType) { diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java index 1bba2de8bd..5bc846c400 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java @@ -20,61 +20,29 @@ import java.util.Comparator; class SubtitleData implements Comparable , Comparator { - private long mStartTimePosUs; - private long mEndTimePosUs; - private String strSubtitle; + public final long startTimePosUs; + public final String strSubtitle; - SubtitleData() + SubtitleData(long startTimePosUs, String strSubtitle) { - mStartTimePosUs = 0l; - mEndTimePosUs = 0l; - strSubtitle = ""; - } - - protected void setStartTimePos(long time) - { - mStartTimePosUs = time; - } - - protected void setEndTimePos(long time) - { - mEndTimePosUs = time; - } - - protected void setSubtitleText(String text) - { - strSubtitle = text; - } - - protected long getStartTimePos() - { - return mStartTimePosUs; - } - - protected long getEndTimePos() - { - return mEndTimePosUs; - } - - protected String getsubtitleText() - { - return strSubtitle; + this.startTimePosUs = startTimePosUs; + this.strSubtitle = strSubtitle; } @Override public int compare(SubtitleData o1 , SubtitleData o2) { - if (o1.getStartTimePos() < o2.getStartTimePos()) + if (o1.startTimePosUs < o2.startTimePosUs) return -1; - if (o1.getStartTimePos() > o2.getStartTimePos()) + if (o1.startTimePosUs > o2.startTimePosUs) return 1; return 0; } @Override public int compareTo(SubtitleData another) { - if (getStartTimePos() < another.getStartTimePos()) + if (startTimePosUs < another.startTimePosUs) return -1; - if (getStartTimePos() > another.getStartTimePos()) + if (startTimePosUs > another.startTimePosUs) return 1; return 0; } diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java index a802761d6b..008d7af078 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java @@ -30,38 +30,20 @@ import java.util.LinkedList; import java.util.List; /** - * A simple Text parser that supports Tx3g presentation profile. - *

- * Supported features in this parser are: - *

    - *
  • content - *
  • core - *
  • presentation - *
  • profile - *
  • structure - *
  • time-offset - *
  • timing - *
  • tickRate - *
  • time-clock-with-frames - *
  • time-clock - *
  • time-offset-with-frames - *
  • time-offset-with-ticks - *
- *

- * @see TTML specification + * A simple Text parser that supports tx3g atom. + * + * Only support to parse a single text track at this version , + * since ExtractorSampleSource does not handle multiple audio/video tracks. + * */ public class TextParser implements SubtitleParser { private static final String TAG = "TextParser"; + private final List subtitleList; - private final List mSubtitleList; - - /** - * Equivalent to {@code TtmlParser(true)}. - */ public TextParser() { Log.i(TAG,"TextParser "); - mSubtitleList = new LinkedList(); + subtitleList = new LinkedList(); } @@ -74,29 +56,27 @@ public class TextParser implements SubtitleParser { text = (text == null) ? "" : text; Log.i(TAG,"parse(" + text + "," + startTimeUs + ")" ); - SubtitleData cue = new SubtitleData(); - cue.setSubtitleText(text); - cue.setStartTimePos(startTimeUs); - mSubtitleList.add(cue); + SubtitleData cue = new SubtitleData(startTimeUs, text); - Collections.sort(mSubtitleList, new Comparator() { + subtitleList.add(cue); + + Collections.sort(subtitleList, new Comparator() { @Override public int compare(SubtitleData o1 , SubtitleData o2) { - if (o1.getStartTimePos() < o2.getStartTimePos()) + if (o1.startTimePosUs < o2.startTimePosUs) return -1; - if (o1.getStartTimePos() > o2.getStartTimePos()) + if (o1.startTimePosUs > o2.startTimePosUs) return 1; return 0; } }); - TextSubtitle textSubtitle = new TextSubtitle(mSubtitleList); + TextSubtitle textSubtitle = new TextSubtitle(subtitleList); return textSubtitle; } @Override public boolean canParse(String mimeType) { - boolean rtn = MimeTypes.TEXT_TX3G.equals(mimeType); - Log.i(TAG,"canParse " + mimeType + "," + rtn); + boolean rtn = MimeTypes.APPLICATION_TX3G.equals(mimeType); return rtn; } } diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java index 32f1a76d24..ad74ec9b80 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java @@ -22,7 +22,7 @@ import com.google.android.exoplayer.text.Cue; import com.google.android.exoplayer.text.Subtitle; /** - * A representation of a TTML subtitle. + * A representation of a tx3g subtitle. */ public final class TextSubtitle implements Subtitle { static String TAG = "TextSubtitle"; @@ -47,7 +47,6 @@ public final class TextSubtitle implements Subtitle { @Override public int getEventTimeCount() { - //LOG.I(TAG,"getEventTimeCount() = " + text.size()); return text.size(); } @@ -55,7 +54,6 @@ public final class TextSubtitle implements Subtitle { public long getEventTime(int index) { if (index > text.size() - 1) return -1; - //LOG.I(TAG,"getEventTime(" + index + ") = " + text.get(index).getStartTimePos()); return text.get(index).getStartTimePos(); } @@ -77,6 +75,7 @@ public final class TextSubtitle implements Subtitle { } private int findTheClosed(long timeUs) { + //TODO : Time complexity is O(n),not good solution. int length = text.size(); for (int i = 0; i < length ; i++) { diff --git a/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java b/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java index dea171b6df..d81ea84991 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java +++ b/library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java @@ -53,12 +53,12 @@ public class MimeTypes { public static final String AUDIO_OPUS = BASE_TYPE_AUDIO + "/opus"; public static final String TEXT_VTT = BASE_TYPE_TEXT + "/vtt"; - public static final String TEXT_TX3G = BASE_TYPE_TEXT + "/tx3g"; public static final String APPLICATION_ID3 = BASE_TYPE_APPLICATION + "/id3"; public static final String APPLICATION_EIA608 = BASE_TYPE_APPLICATION + "/eia-608"; public static final String APPLICATION_TTML = BASE_TYPE_APPLICATION + "/ttml+xml"; public static final String APPLICATION_M3U8 = BASE_TYPE_APPLICATION + "/x-mpegURL"; + public static final String APPLICATION_TX3G = BASE_TYPE_APPLICATION + "/x-quicktime-tx3g"; private MimeTypes() {} From fd2ebc767c9f9e565df02c99f4c719c66aadb193 Mon Sep 17 00:00:00 2001 From: ood_tsen Date: Wed, 3 Jun 2015 20:02:42 +0800 Subject: [PATCH 4/5] keep maximum number of subtitles to four. --- .../exoplayer/text/tx3g/SubtitleData.java | 9 ++++++--- .../exoplayer/text/tx3g/TextParser.java | 18 ++++++++---------- .../exoplayer/text/tx3g/TextSubtitle.java | 12 ++++++------ 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java index 5bc846c400..ce4603b29d 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/SubtitleData.java @@ -18,15 +18,18 @@ package com.google.android.exoplayer.text.tx3g; import java.util.Comparator; +/** + * A representation of a single tx3g. + */ class SubtitleData implements Comparable , Comparator { public final long startTimePosUs; - public final String strSubtitle; + public final String subtitle; - SubtitleData(long startTimePosUs, String strSubtitle) + SubtitleData(long startTimePosUs, String subtitle) { this.startTimePosUs = startTimePosUs; - this.strSubtitle = strSubtitle; + this.subtitle = subtitle; } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java index 008d7af078..927818c32a 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java @@ -19,8 +19,6 @@ import com.google.android.exoplayer.text.Subtitle; import com.google.android.exoplayer.text.SubtitleParser; import com.google.android.exoplayer.util.MimeTypes; -import android.util.Log; - import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; @@ -40,13 +38,12 @@ public class TextParser implements SubtitleParser { private static final String TAG = "TextParser"; private final List subtitleList; - + private static final int MAX_SUBTITLE_COUNT = 4; public TextParser() { - Log.i(TAG,"TextParser "); + subtitleList = new LinkedList(); } - @Override public Subtitle parse(InputStream inputStream, String inputEncoding, long startTimeUs) throws IOException { @@ -54,10 +51,13 @@ public class TextParser implements SubtitleParser { DataInputStream in = new DataInputStream(inputStream); String text = in.readUTF(); text = (text == null) ? "" : text; - Log.i(TAG,"parse(" + text + "," + startTimeUs + ")" ); SubtitleData cue = new SubtitleData(startTimeUs, text); + while (subtitleList.size() > MAX_SUBTITLE_COUNT) { + subtitleList.remove(0); + } + subtitleList.add(cue); Collections.sort(subtitleList, new Comparator() { @@ -70,13 +70,11 @@ public class TextParser implements SubtitleParser { return 0; } }); - TextSubtitle textSubtitle = new TextSubtitle(subtitleList); - return textSubtitle; + return new TextSubtitle(subtitleList); } @Override public boolean canParse(String mimeType) { - boolean rtn = MimeTypes.APPLICATION_TX3G.equals(mimeType); - return rtn; + return MimeTypes.APPLICATION_TX3G.equals(mimeType); } } diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java index ad74ec9b80..c59389b4bb 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextSubtitle.java @@ -34,7 +34,7 @@ public final class TextSubtitle implements Subtitle { @Override public long getStartTime() { - return text.get(0).getStartTimePos(); + return text.get(0).startTimePosUs; } @Override @@ -54,12 +54,12 @@ public final class TextSubtitle implements Subtitle { public long getEventTime(int index) { if (index > text.size() - 1) return -1; - return text.get(index).getStartTimePos(); + return text.get(index).startTimePosUs; } @Override public long getLastEventTime() { - return text.get(0).getStartTimePos(); + return text.get(0).startTimePosUs; } @Override @@ -68,7 +68,7 @@ public final class TextSubtitle implements Subtitle { List list = new ArrayList<>(); if (index == -1) return null; - String str = text.get(index).getsubtitleText(); + String str = text.get(index).subtitle; list.add(new Cue(str)); return list; @@ -80,10 +80,10 @@ public final class TextSubtitle implements Subtitle { int length = text.size(); for (int i = 0; i < length ; i++) { SubtitleData data = text.get(i); - boolean bCheckFront = data.getStartTimePos() <= timeUs ; + boolean bCheckFront = data.startTimePosUs <= timeUs ; boolean bCheckEnd = false; if (i + 1 < length) { - bCheckEnd = text.get(i + 1).getStartTimePos() > timeUs ; + bCheckEnd = text.get(i + 1).startTimePosUs > timeUs ; } else if (i + 1 == length) { bCheckEnd = true; } From b95b0aad5c7c6418b788fc70a91c2f534d52972b Mon Sep 17 00:00:00 2001 From: ood_tsen Date: Wed, 3 Jun 2015 20:28:30 +0800 Subject: [PATCH 5/5] clean the list while forward seek. --- .../android/exoplayer/text/tx3g/TextParser.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java index 927818c32a..7f4098d8e5 100644 --- a/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java +++ b/library/src/main/java/com/google/android/exoplayer/text/tx3g/TextParser.java @@ -54,10 +54,18 @@ public class TextParser implements SubtitleParser { SubtitleData cue = new SubtitleData(startTimeUs, text); - while (subtitleList.size() > MAX_SUBTITLE_COUNT) { - subtitleList.remove(0); - } + //try to resize the list. + if (subtitleList.size() > 0) { + long lastTimeUs = subtitleList.get(subtitleList.size() - 1).startTimePosUs; + if (startTimeUs < lastTimeUs) { + //when forward seek + subtitleList.clear(); + } + while (subtitleList.size() > MAX_SUBTITLE_COUNT) { + subtitleList.remove(0); + } + } subtitleList.add(cue); Collections.sort(subtitleList, new Comparator() {