@Test public void testDecodeTxxxFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("TXXX", new byte[] {3, 0, 109, 100, 105, 97, 108, 111, 103, 95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); TextInformationFrame textInformationFrame = (TextInformationFrame) metadata.get(0); assertThat(textInformationFrame.id).isEqualTo("TXXX"); assertThat(textInformationFrame.description).isEmpty(); assertThat(textInformationFrame.value).isEqualTo("mdialog_VINDICO1527664_start"); // Test empty. rawId3 = buildSingleFrameTag("TXXX", new byte[0]); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(0); // Test encoding byte only. rawId3 = buildSingleFrameTag("TXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8}); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); textInformationFrame = (TextInformationFrame) metadata.get(0); assertThat(textInformationFrame.id).isEqualTo("TXXX"); assertThat(textInformationFrame.description).isEmpty(); assertThat(textInformationFrame.value).isEmpty(); }
@Test public void testDecodeTextInformationFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("TIT2", new byte[] {3, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); TextInformationFrame textInformationFrame = (TextInformationFrame) metadata.get(0); assertThat(textInformationFrame.id).isEqualTo("TIT2"); assertThat(textInformationFrame.description).isNull(); assertThat(textInformationFrame.value).isEqualTo("Hello World"); // Test empty. rawId3 = buildSingleFrameTag("TIT2", new byte[0]); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(0); // Test encoding byte only. rawId3 = buildSingleFrameTag("TIT2", new byte[] {ID3_TEXT_ENCODING_UTF_8}); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); textInformationFrame = (TextInformationFrame) metadata.get(0); assertThat(textInformationFrame.id).isEqualTo("TIT2"); assertThat(textInformationFrame.description).isNull(); assertThat(textInformationFrame.value).isEmpty(); }
@Test public void testDecodeUrlLinkFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("WCOM", new byte[] {104, 116, 116, 112, 115, 58, 47, 47, 116, 101, 115, 116, 46, 99, 111, 109, 47, 97, 98, 99, 63, 100, 101, 102}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); UrlLinkFrame urlLinkFrame = (UrlLinkFrame) metadata.get(0); assertThat(urlLinkFrame.id).isEqualTo("WCOM"); assertThat(urlLinkFrame.description).isNull(); assertThat(urlLinkFrame.url).isEqualTo("https://test.com/abc?def"); // Test empty. rawId3 = buildSingleFrameTag("WCOM", new byte[0]); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); urlLinkFrame = (UrlLinkFrame) metadata.get(0); assertThat(urlLinkFrame.id).isEqualTo("WCOM"); assertThat(urlLinkFrame.description).isNull(); assertThat(urlLinkFrame.url).isEmpty(); }
@Test public void testDecodePrivFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("PRIV", new byte[] {116, 101, 115, 116, 0, 1, 2, 3, 4}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); PrivFrame privFrame = (PrivFrame) metadata.get(0); assertThat(privFrame.owner).isEqualTo("test"); assertThat(privFrame.privateData).isEqualTo(new byte[]{1, 2, 3, 4}); // Test empty. rawId3 = buildSingleFrameTag("PRIV", new byte[0]); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); privFrame = (PrivFrame) metadata.get(0); assertThat(privFrame.owner).isEmpty(); assertThat(privFrame.privateData).isEqualTo(new byte[0]); }
@Test public void testDecodeCommentFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("COMM", new byte[] {ID3_TEXT_ENCODING_UTF_8, 101, 110, 103, 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 0, 116, 101, 120, 116, 0}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); CommentFrame commentFrame = (CommentFrame) metadata.get(0); assertThat(commentFrame.language).isEqualTo("eng"); assertThat(commentFrame.description).isEqualTo("description"); assertThat(commentFrame.text).isEqualTo("text"); // Test empty. rawId3 = buildSingleFrameTag("COMM", new byte[0]); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(0); // Test language only. rawId3 = buildSingleFrameTag("COMM", new byte[] {ID3_TEXT_ENCODING_UTF_8, 101, 110, 103}); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); commentFrame = (CommentFrame) metadata.get(0); assertThat(commentFrame.language).isEqualTo("eng"); assertThat(commentFrame.description).isEmpty(); assertThat(commentFrame.text).isEmpty(); }
@Test public void testWrappedAroundTimeSignalCommand() throws MetadataDecoderException { byte[] rawTimeSignalSection = new byte[] { 0, // table_id. (byte) 0x80, // section_syntax_indicator, private_indicator, reserved, section_length(4). 0x14, // section_length(8). 0x00, // protocol_version. 0x00, // encrypted_packet, encryption_algorithm, pts_adjustment(1). 0x00, 0x00, 0x00, 0x00, // pts_adjustment(32). 0x00, // cw_index. 0x00, // tier(8). 0x00, // tier(4), splice_command_length(4). 0x05, // splice_command_length(8). 0x06, // splice_command_type = time_signal. // Start of splice_time(). (byte) 0x80, // time_specified_flag, reserved, pts_time(1). 0x52, 0x03, 0x02, (byte) 0x8f, // pts_time(32). PTS for a second after playback position. 0x00, 0x00, 0x00, 0x00}; // CRC_32 (ignored, check happens at extraction). // The playback position is 57:15:58.43 approximately. // With this offset, the playback position pts before wrapping is 0x451ebf851. Metadata metadata = feedInputBuffer(rawTimeSignalSection, 0x3000000000L, -0x50000L); assertThat(metadata.length()).isEqualTo(1); assertThat(((TimeSignalCommand) metadata.get(0)).playbackPositionUs) .isEqualTo(removePtsConversionPrecisionError(0x3001000000L, inputBuffer.subsampleOffsetUs)); }
/** * @param id3Buffer A {@link ParsableByteArray} from which data should be read. * @return The size of ID3 frames in bytes, excluding the header and footer. * @throws ParserException If ID3 file identifier != "ID3". */ private static int decodeId3Header(ParsableByteArray id3Buffer) throws MetadataDecoderException { int id1 = id3Buffer.readUnsignedByte(); int id2 = id3Buffer.readUnsignedByte(); int id3 = id3Buffer.readUnsignedByte(); if (id1 != 'I' || id2 != 'D' || id3 != '3') { throw new MetadataDecoderException(String.format(Locale.US, "Unexpected ID3 file identifier, expected \"ID3\", actual \"%c%c%c\".", id1, id2, id3)); } id3Buffer.skipBytes(2); // Skip version. int flags = id3Buffer.readUnsignedByte(); int id3Size = id3Buffer.readSynchSafeInt(); // Check if extended header presents. if ((flags & 0x2) != 0) { int extendedHeaderSize = id3Buffer.readSynchSafeInt(); if (extendedHeaderSize > 4) { id3Buffer.skipBytes(extendedHeaderSize - 4); } id3Size -= extendedHeaderSize; } // Check if footer presents. if ((flags & 0x8) != 0) { id3Size -= 10; } return id3Size; }
public void testDecodeTxxxFrame() throws MetadataDecoderException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 41, 84, 88, 88, 88, 0, 0, 0, 31, 0, 0, 3, 0, 109, 100, 105, 97, 108, 111, 103, 95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0}; Id3Decoder decoder = new Id3Decoder(); List<Id3Frame> id3Frames = decoder.decode(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); TxxxFrame txxxFrame = (TxxxFrame) id3Frames.get(0); assertEquals("", txxxFrame.description); assertEquals("mdialog_VINDICO1527664_start", txxxFrame.value); }
public void testDecodeApicFrame() throws MetadataDecoderException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 45, 65, 80, 73, 67, 0, 0, 0, 35, 0, 0, 3, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 0, 16, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; Id3Decoder decoder = new Id3Decoder(); List<Id3Frame> id3Frames = decoder.decode(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); ApicFrame apicFrame = (ApicFrame) id3Frames.get(0); assertEquals("image/jpeg", apicFrame.mimeType); assertEquals(16, apicFrame.pictureType); assertEquals("Hello World", apicFrame.description); assertEquals(10, apicFrame.pictureData.length); MoreAsserts.assertEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, apicFrame.pictureData); }
public void testDecodeTextInformationFrame() throws MetadataDecoderException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 23, 84, 73, 84, 50, 0, 0, 0, 13, 0, 0, 3, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0}; Id3Decoder decoder = new Id3Decoder(); List<Id3Frame> id3Frames = decoder.decode(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); TextInformationFrame textInformationFrame = (TextInformationFrame) id3Frames.get(0); assertEquals("TIT2", textInformationFrame.id); assertEquals("Hello World", textInformationFrame.description); }
@Test public void testDecodeWxxxFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("WXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8, 116, 101, 115, 116, 0, 104, 116, 116, 112, 115, 58, 47, 47, 116, 101, 115, 116, 46, 99, 111, 109, 47, 97, 98, 99, 63, 100, 101, 102}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); UrlLinkFrame urlLinkFrame = (UrlLinkFrame) metadata.get(0); assertThat(urlLinkFrame.id).isEqualTo("WXXX"); assertThat(urlLinkFrame.description).isEqualTo("test"); assertThat(urlLinkFrame.url).isEqualTo("https://test.com/abc?def"); // Test empty. rawId3 = buildSingleFrameTag("WXXX", new byte[0]); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(0); // Test encoding byte only. rawId3 = buildSingleFrameTag("WXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8}); metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); urlLinkFrame = (UrlLinkFrame) metadata.get(0); assertThat(urlLinkFrame.id).isEqualTo("WXXX"); assertThat(urlLinkFrame.description).isEmpty(); assertThat(urlLinkFrame.url).isEmpty(); }
@Test public void testDecodeApicFrame() throws MetadataDecoderException { byte[] rawId3 = buildSingleFrameTag("APIC", new byte[] {3, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 0, 16, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0}); Id3Decoder decoder = new Id3Decoder(); Metadata metadata = decoder.decode(rawId3, rawId3.length); assertThat(metadata.length()).isEqualTo(1); ApicFrame apicFrame = (ApicFrame) metadata.get(0); assertThat(apicFrame.mimeType).isEqualTo("image/jpeg"); assertThat(apicFrame.pictureType).isEqualTo(16); assertThat(apicFrame.description).isEqualTo("Hello World"); assertThat(apicFrame.pictureData).hasLength(10); assertThat(apicFrame.pictureData).isEqualTo(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}); }
private Metadata feedInputBuffer(byte[] data, long timeUs, long subsampleOffset) throws MetadataDecoderException{ inputBuffer.clear(); inputBuffer.data = ByteBuffer.allocate(data.length).put(data); inputBuffer.timeUs = timeUs; inputBuffer.subsampleOffsetUs = subsampleOffset; return decoder.decode(inputBuffer); }