parseTagsSync method
Implementation
bool parseTagsSync() {
List<int> _tag;
_tag = mp3Bytes.sublist(0, 3);
if (latin1.decode(_tag) == 'ID3') {
final int major_v = mp3Bytes[3];
final int revision_v = mp3Bytes[4];
final int flag = mp3Bytes[5];
final bool unsync = (0x40 & flag != 0);
final bool extended = (0x20 & flag != 0);
final bool experimental = (0x10 & flag != 0);
metaTags['Version'] = 'v2.$major_v.$revision_v';
if (extended) {
print('Extended id3v2 tags are not supported yet!');
} else if (unsync) {
print('Unsync id3v2 tags are not supported yet!');
} else if (experimental) {
print('Experimental id3v2 tag');
}
int cb = 10;
Map<String, String> frames_db = FRAMESv2_3;
int frameNameLength = 4;
int frameSizeLength = 4;
int frameTagLength = 2;
if (major_v == 2) {
frames_db = FRAMESv2_2;
frameNameLength = 3;
frameSizeLength = 3;
frameTagLength = 0;
}
final int frameHeaderLength =
frameNameLength + frameSizeLength + frameTagLength;
while (true) {
final List<int> frameHeader =
mp3Bytes.sublist(cb, cb + frameHeaderLength);
final List<int> frameName = frameHeader.sublist(0, frameNameLength);
final RegExp exp = RegExp(r'[A-Z0-9]+');
if (latin1.decode(frameName) !=
exp.stringMatch(latin1.decode(frameName))) {
break;
}
final int frameSize = parseSize(
frameHeader.sublist(
frameNameLength, frameNameLength + frameSizeLength),
major_v);
final List<int> frameContent = mp3Bytes.sublist(
cb + frameHeaderLength, cb + frameHeaderLength + frameSize);
if (frames_db[latin1.decode(frameName)] == FRAMESv2_3['APIC']) {
final Map<String, String> apic = {
'mime': '',
'textEncoding': frameContent[0].toString(),
'picType': '',
'description': '',
'base64': ''
};
final frame = _MP3FrameParser(frameContent);
frame.readEncoding();
// In ID3v2.2 the MIME type is always 3 characters
if (major_v == 2) {
apic['mime'] = latin1.decode(frame.readBytes(3));
} else {
apic['mime'] = frame.readLatin1String();
}
apic['picType'] = PICTYPE[frame.readBytes(1).first] ?? 'Unknown';
apic['description'] = frame.readString(checkEncoding: false);
apic['base64'] = base64.encode(frame.readRemainingBytes());
metaTags['APIC'] = apic;
} else if (frames_db[latin1.decode(frameName)] == FRAMESv2_3['USLT']) {
final frame = _MP3FrameParser(frameContent);
frame.readEncoding();
final language = latin1.decode(frame.readBytes(3));
String contentDescriptor;
contentDescriptor = frame.readString(checkEncoding: false);
final lyrics = (frame.remainingBytes > 0)
? frame.readString(checkEncoding: false, terminator: false)
: contentDescriptor;
if (frame.remainingBytes == 0) {
contentDescriptor = '';
}
metaTags['USLT'] = {
'language': language,
'contentDescriptor': contentDescriptor,
'lyrics': lyrics
};
} else if (frames_db[latin1.decode(frameName)] == FRAMESv2_3['WXXX']) {
final frame = _MP3FrameParser(frameContent);
metaTags['WXXX'] = {
'description': frame.readString(),
'url': frame.readLatin1String(terminator: false)
};
} else if (frames_db[latin1.decode(frameName)] == FRAMESv2_3['COMM']) {
final frame = _MP3FrameParser(frameContent);
frame.readEncoding();
final language = latin1.decode(frame.readBytes(3));
final shortDescription = frame.readString(checkEncoding: false);
final text =
frame.readString(terminator: false, checkEncoding: false);
if (metaTags['COMM'] == null) {
metaTags['COMM'] = {};
if (metaTags['COMM'][language] == null) {
metaTags['COMM'][language] = {};
}
}
metaTags['COMM'][language][shortDescription] = text;
} else if (frames_db[latin1.decode(frameName)] == FRAMESv2_3['MCDI'] ||
frames_db[latin1.decode(frameName)] == FRAMESv2_3['RVAD']) {
// Binary data
metaTags[frames_db[latin1.decode(frameName)] ??
latin1.decode(frameName)] = frameContent;
} else {
final String tag =
frames_db[latin1.decode(frameName)] ?? latin1.decode(frameName);
metaTags[tag] =
_MP3FrameParser(frameContent).readString(terminator: false);
}
cb += frameHeaderLength + frameSize;
}
return true;
}
final List<int> _header =
mp3Bytes.sublist(mp3Bytes.length - 128, mp3Bytes.length);
_tag = _header.sublist(0, 3);
if (latin1.decode(_tag).toLowerCase() == 'tag') {
metaTags['Version'] = '1.0';
final List<int> _title = _header.sublist(3, 33);
final List<int> _artist = _header.sublist(33, 63);
final List<int> _album = _header.sublist(63, 93);
final List<int> _year = _header.sublist(93, 97);
final List<int> _comment = _header.sublist(97, 127);
final int _genre = _header[127];
metaTags['Title'] = latin1.decode(_title).trim();
metaTags['Artist'] = latin1.decode(_artist).trim();
metaTags['Album'] = latin1.decode(_album).trim();
metaTags['Year'] = latin1.decode(_year).trim();
metaTags['Comment'] = latin1.decode(_comment).trim();
metaTags['Genre'] = GENREv1[_genre];
return true;
}
return false;
}