mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2024-12-23 07:25:25 +01:00
Added support for ID3 2.4 tag, resolved problems with frame size calculation
This commit is contained in:
parent
02586d3026
commit
8b3c7d6723
@ -2,6 +2,7 @@ package de.danoeh.antennapod.util.id3reader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -67,7 +68,10 @@ public class ChapterReader extends ID3Reader {
|
||||
int descriptionLength = readString(null, input, header.getSize());
|
||||
StringBuffer link = new StringBuffer();
|
||||
readISOString(link, input, header.getSize() - descriptionLength);
|
||||
currentChapter.setLink(link.toString());
|
||||
String decodedLink = URLDecoder.decode(link.toString(), "UTF-8");
|
||||
|
||||
currentChapter.setLink(decodedLink);
|
||||
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "Found link: " + currentChapter.getLink());
|
||||
return ID3Reader.ACTION_DONT_SKIP;
|
||||
}
|
||||
|
@ -24,7 +24,11 @@ public class ID3Reader {
|
||||
|
||||
protected int readerPosition;
|
||||
|
||||
private static final byte ENCODING_UNICODE = 1;
|
||||
private static final byte ENCODING_UTF16_WITH_BOM = 1;
|
||||
private static final byte ENCODING_UTF16_WITHOUT_BOM = 2;
|
||||
private static final byte ENCODING_UTF8 = 3;
|
||||
|
||||
private TagHeader tagHeader;
|
||||
|
||||
public ID3Reader() {
|
||||
}
|
||||
@ -34,7 +38,7 @@ public class ID3Reader {
|
||||
int rc;
|
||||
readerPosition = 0;
|
||||
char[] tagHeaderSource = readBytes(input, HEADER_LENGTH);
|
||||
TagHeader tagHeader = createTagHeader(tagHeaderSource);
|
||||
tagHeader = createTagHeader(tagHeaderSource);
|
||||
if (tagHeader == null) {
|
||||
onNoTagHeaderFound();
|
||||
} else {
|
||||
@ -124,12 +128,12 @@ public class ID3Reader {
|
||||
+ HEADER_LENGTH);
|
||||
}
|
||||
if (hasTag) {
|
||||
String id = null;
|
||||
id = new String(source, 0, ID3_LENGTH);
|
||||
String id = new String(source, 0, ID3_LENGTH);
|
||||
char version = (char) ((source[3] << 8) | source[4]);
|
||||
byte flags = (byte) source[5];
|
||||
int size = (source[6] << 24) | (source[7] << 16) | (source[8] << 8)
|
||||
| source[9];
|
||||
size = unsynchsafe(size);
|
||||
return new TagHeader(id, size, version, flags);
|
||||
} else {
|
||||
return null;
|
||||
@ -142,23 +146,41 @@ public class ID3Reader {
|
||||
throw new ID3ReaderException("Length of header must be "
|
||||
+ HEADER_LENGTH);
|
||||
}
|
||||
String id = null;
|
||||
id = new String(source, 0, FRAME_ID_LENGTH);
|
||||
int size = (((int) source[4]) << 24) | (((int) source[5]) << 16)
|
||||
| (((int) source[6]) << 8) | source[7];
|
||||
String id = new String(source, 0, FRAME_ID_LENGTH);
|
||||
|
||||
int size = (((int) source[4]) << 24) | (((int) source[5]) << 16)
|
||||
| (((int) source[6]) << 8) | source[7];
|
||||
if (tagHeader != null && tagHeader.getVersion() >= 0x0400) {
|
||||
size = unsynchsafe(size);
|
||||
}
|
||||
char flags = (char) ((source[8] << 8) | source[9]);
|
||||
return new FrameHeader(id, size, flags);
|
||||
}
|
||||
|
||||
private int unsynchsafe(int in) {
|
||||
int out = 0;
|
||||
int mask = 0x7F000000;
|
||||
|
||||
while (mask != 0) {
|
||||
out >>= 1;
|
||||
out |= in & mask;
|
||||
mask >>= 8;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
protected int readString(StringBuffer buffer, InputStream input, int max) throws IOException,
|
||||
ID3ReaderException {
|
||||
if (max > 0) {
|
||||
char[] encoding = readBytes(input, 1);
|
||||
max--;
|
||||
|
||||
if (encoding[0] == ENCODING_UNICODE) {
|
||||
return readUnicodeString(buffer, input, max) + 1; // take encoding byte into account
|
||||
} else {
|
||||
if (encoding[0] == ENCODING_UTF16_WITH_BOM || encoding[0] == ENCODING_UTF16_WITHOUT_BOM) {
|
||||
return readUnicodeString(buffer, input, max, Charset.forName("UTF-16")) + 1; // take encoding byte into account
|
||||
} else if (encoding[0] == ENCODING_UTF8) {
|
||||
return readUnicodeString(buffer, input, max, Charset.forName("UTF-8")) + 1; // take encoding byte into account
|
||||
} else {
|
||||
return readISOString(buffer, input, max) + 1; // take encoding byte into account
|
||||
}
|
||||
} else {
|
||||
@ -182,7 +204,7 @@ public class ID3Reader {
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
private int readUnicodeString(StringBuffer strBuffer, InputStream input, int max)
|
||||
private int readUnicodeString(StringBuffer strBuffer, InputStream input, int max, Charset charset)
|
||||
throws IOException, ID3ReaderException {
|
||||
byte[] buffer = new byte[max];
|
||||
int c, cZero = -1;
|
||||
@ -203,7 +225,6 @@ public class ID3Reader {
|
||||
cZero = -1;
|
||||
}
|
||||
}
|
||||
Charset charset = Charset.forName("UTF-16");
|
||||
if (strBuffer != null) {
|
||||
strBuffer.append(charset.newDecoder().decode(ByteBuffer.wrap(buffer)).toString());
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ public class FrameHeader extends Header {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FrameHeader [flags=" + Integer.toString(flags) + ", id=" + id + ", size=" + size
|
||||
+ "]";
|
||||
}
|
||||
return String.format("FrameHeader [flags=%s, id=%s, size=%s]", Integer.toBinaryString(flags), id, Integer.toBinaryString(size));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user