diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/ChapterTOCFrameTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/ChapterTocFrameTest.java similarity index 77% rename from library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/ChapterTOCFrameTest.java rename to library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/ChapterTocFrameTest.java index b0819ff427..9641de7669 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/ChapterTOCFrameTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/ChapterTocFrameTest.java @@ -19,9 +19,9 @@ import android.os.Parcel; import junit.framework.TestCase; /** - * Test for {@link ChapterTOCFrame}. + * Test for {@link ChapterTocFrame}. */ -public final class ChapterTOCFrameTest extends TestCase { +public final class ChapterTocFrameTest extends TestCase { public void testParcelable() { String[] children = new String[] {"child0", "child1"}; @@ -29,15 +29,15 @@ public final class ChapterTOCFrameTest extends TestCase { new TextInformationFrame("TIT2", null, "title"), new UrlLinkFrame("WXXX", "description", "url") }; - ChapterTOCFrame chapterTOCFrameToParcel = new ChapterTOCFrame("id", false, true, children, + ChapterTocFrame chapterTocFrameToParcel = new ChapterTocFrame("id", false, true, children, subFrames); Parcel parcel = Parcel.obtain(); - chapterTOCFrameToParcel.writeToParcel(parcel, 0); + chapterTocFrameToParcel.writeToParcel(parcel, 0); parcel.setDataPosition(0); - ChapterTOCFrame chapterTOCFrameFromParcel = ChapterTOCFrame.CREATOR.createFromParcel(parcel); - assertEquals(chapterTOCFrameToParcel, chapterTOCFrameFromParcel); + ChapterTocFrame chapterTocFrameFromParcel = ChapterTocFrame.CREATOR.createFromParcel(parcel); + assertEquals(chapterTocFrameToParcel, chapterTocFrameFromParcel); parcel.recycle(); } diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterFrame.java b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterFrame.java index 22fd0d5fe4..c82f982aa7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterFrame.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterFrame.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.metadata.id3; import android.os.Parcel; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.util.Util; import java.util.Arrays; @@ -27,18 +28,24 @@ public final class ChapterFrame extends Id3Frame { public static final String ID = "CHAP"; public final String chapterId; - public final int startTime; - public final int endTime; - public final int startOffset; - public final int endOffset; + public final int startTimeMs; + public final int endTimeMs; + /** + * The byte offset of the start of the chapter, or {@link C#POSITION_UNSET} if not set. + */ + public final long startOffset; + /** + * The byte offset of the end of the chapter, or {@link C#POSITION_UNSET} if not set. + */ + public final long endOffset; private final Id3Frame[] subFrames; - public ChapterFrame(String chapterId, int startTime, int endTime, int startOffset, int endOffset, - Id3Frame[] subFrames) { + public ChapterFrame(String chapterId, int startTimeMs, int endTimeMs, long startOffset, + long endOffset, Id3Frame[] subFrames) { super(ID); this.chapterId = chapterId; - this.startTime = startTime; - this.endTime = endTime; + this.startTimeMs = startTimeMs; + this.endTimeMs = endTimeMs; this.startOffset = startOffset; this.endOffset = endOffset; this.subFrames = subFrames; @@ -47,10 +54,10 @@ public final class ChapterFrame extends Id3Frame { /* package */ ChapterFrame(Parcel in) { super(ID); this.chapterId = in.readString(); - this.startTime = in.readInt(); - this.endTime = in.readInt(); - this.startOffset = in.readInt(); - this.endOffset = in.readInt(); + this.startTimeMs = in.readInt(); + this.endTimeMs = in.readInt(); + this.startOffset = in.readLong(); + this.endOffset = in.readLong(); int subFrameCount = in.readInt(); subFrames = new Id3Frame[subFrameCount]; for (int i = 0; i < subFrameCount; i++) { @@ -58,6 +65,20 @@ public final class ChapterFrame extends Id3Frame { } } + /** + * Returns the number of sub-frames. + */ + public int getSubFrameCount() { + return subFrames.length; + } + + /** + * Returns the sub-frame at {@code index}. + */ + public Id3Frame getSubFrame(int index) { + return subFrames[index]; + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -67,8 +88,8 @@ public final class ChapterFrame extends Id3Frame { return false; } ChapterFrame other = (ChapterFrame) obj; - return startTime == other.startTime - && endTime == other.endTime + return startTimeMs == other.startTimeMs + && endTimeMs == other.endTimeMs && startOffset == other.startOffset && endOffset == other.endOffset && Util.areEqual(chapterId, other.chapterId) @@ -78,10 +99,10 @@ public final class ChapterFrame extends Id3Frame { @Override public int hashCode() { int result = 17; - result = 31 * result + startTime; - result = 31 * result + endTime; - result = 31 * result + startOffset; - result = 31 * result + endOffset; + result = 31 * result + startTimeMs; + result = 31 * result + endTimeMs; + result = 31 * result + (int) startOffset; + result = 31 * result + (int) endOffset; result = 31 * result + (chapterId != null ? chapterId.hashCode() : 0); return result; } @@ -89,13 +110,13 @@ public final class ChapterFrame extends Id3Frame { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(chapterId); - dest.writeInt(startTime); - dest.writeInt(endTime); - dest.writeInt(startOffset); - dest.writeInt(endOffset); + dest.writeInt(startTimeMs); + dest.writeInt(endTimeMs); + dest.writeLong(startOffset); + dest.writeLong(endOffset); dest.writeInt(subFrames.length); - for (int i = 0; i < subFrames.length; i++) { - dest.writeParcelable(subFrames[i], 0); + for (Id3Frame subFrame : subFrames) { + dest.writeParcelable(subFrame, 0); } } diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterTOCFrame.java b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterTocFrame.java similarity index 77% rename from library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterTOCFrame.java rename to library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterTocFrame.java index 6dfcf9f104..d71d0863c7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterTOCFrame.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/ChapterTocFrame.java @@ -16,15 +16,13 @@ package com.google.android.exoplayer2.metadata.id3; import android.os.Parcel; - import com.google.android.exoplayer2.util.Util; - import java.util.Arrays; /** * Chapter table of contents ID3 frame. */ -public final class ChapterTOCFrame extends Id3Frame { +public final class ChapterTocFrame extends Id3Frame { public static final String ID = "CTOC"; @@ -32,9 +30,9 @@ public final class ChapterTOCFrame extends Id3Frame { public final boolean isRoot; public final boolean isOrdered; public final String[] children; - public final Id3Frame[] subFrames; + private final Id3Frame[] subFrames; - public ChapterTOCFrame(String elementId, boolean isRoot, boolean isOrdered, String[] children, + public ChapterTocFrame(String elementId, boolean isRoot, boolean isOrdered, String[] children, Id3Frame[] subFrames) { super(ID); this.elementId = elementId; @@ -44,7 +42,7 @@ public final class ChapterTOCFrame extends Id3Frame { this.subFrames = subFrames; } - /* package */ ChapterTOCFrame(Parcel in) { + /* package */ ChapterTocFrame(Parcel in) { super(ID); this.elementId = in.readString(); this.isRoot = in.readByte() != 0; @@ -57,6 +55,20 @@ public final class ChapterTOCFrame extends Id3Frame { } } + /** + * Returns the number of sub-frames. + */ + public int getSubFrameCount() { + return subFrames.length; + } + + /** + * Returns the sub-frame at {@code index}. + */ + public Id3Frame getSubFrame(int index) { + return subFrames[index]; + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -65,7 +77,7 @@ public final class ChapterTOCFrame extends Id3Frame { if (obj == null || getClass() != obj.getClass()) { return false; } - ChapterTOCFrame other = (ChapterTOCFrame) obj; + ChapterTocFrame other = (ChapterTocFrame) obj; return isRoot == other.isRoot && isOrdered == other.isOrdered && Util.areEqual(elementId, other.elementId) @@ -94,16 +106,16 @@ public final class ChapterTOCFrame extends Id3Frame { } } - public static final Creator CREATOR = new Creator() { + public static final Creator CREATOR = new Creator() { @Override - public ChapterTOCFrame createFromParcel(Parcel in) { - return new ChapterTOCFrame(in); + public ChapterTocFrame createFromParcel(Parcel in) { + return new ChapterTocFrame(in); } @Override - public ChapterTOCFrame[] newArray(int size) { - return new ChapterTOCFrame[size]; + public ChapterTocFrame[] newArray(int size) { + return new ChapterTocFrame[size]; } }; diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java index 266aad6f70..9c3aa03271 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.metadata.id3; import android.util.Log; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.MetadataDecoder; import com.google.android.exoplayer2.metadata.MetadataInputBuffer; @@ -368,8 +369,8 @@ public final class Id3Decoder implements MetadataDecoder { return new TextInformationFrame(id, null, value); } - private static UrlLinkFrame decodeWxxxFrame(ParsableByteArray id3Data, - int frameSize) throws UnsupportedEncodingException { + private static UrlLinkFrame decodeWxxxFrame(ParsableByteArray id3Data, int frameSize) + throws UnsupportedEncodingException { int encoding = id3Data.readUnsignedByte(); String charset = getCharsetName(encoding); @@ -523,8 +524,14 @@ public final class Id3Decoder implements MetadataDecoder { int startTime = id3Data.readInt(); int endTime = id3Data.readInt(); - int startOffset = id3Data.readInt(); - int endOffset = id3Data.readInt(); + long startOffset = id3Data.readUnsignedInt(); + if (startOffset == 0xFFFFFFFFL) { + startOffset = C.POSITION_UNSET; + } + long endOffset = id3Data.readUnsignedInt(); + if (endOffset == 0xFFFFFFFFL) { + endOffset = C.POSITION_UNSET; + } ArrayList subFrames = new ArrayList<>(); int limit = framePosition + frameSize; @@ -541,7 +548,7 @@ public final class Id3Decoder implements MetadataDecoder { return new ChapterFrame(chapterId, startTime, endTime, startOffset, endOffset, subFrameArray); } - private static ChapterTOCFrame decodeChapterTOCFrame(ParsableByteArray id3Data, int frameSize, + private static ChapterTocFrame decodeChapterTOCFrame(ParsableByteArray id3Data, int frameSize, int majorVersion, boolean unsignedIntFrameSizeHack, int frameHeaderSize) throws UnsupportedEncodingException { int framePosition = id3Data.getPosition(); @@ -575,7 +582,7 @@ public final class Id3Decoder implements MetadataDecoder { Id3Frame[] subFrameArray = new Id3Frame[subFrames.size()]; subFrames.toArray(subFrameArray); - return new ChapterTOCFrame(elementId, isRoot, isOrdered, children, subFrameArray); + return new ChapterTocFrame(elementId, isRoot, isOrdered, children, subFrameArray); } private static BinaryFrame decodeBinaryFrame(ParsableByteArray id3Data, int frameSize, diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/UrlLinkFrame.java b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/UrlLinkFrame.java index 7936d50b55..2148b921e1 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/UrlLinkFrame.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/UrlLinkFrame.java @@ -17,7 +17,6 @@ package com.google.android.exoplayer2.metadata.id3; import android.os.Parcel; import android.os.Parcelable; - import com.google.android.exoplayer2.util.Util; /**