use of org.jaudiotagger.tag.mp4.field.Mp4TagCoverField in project MusicDNA by harjot-oberai.
the class Mp4TagReader method createMp4Field.
/**
* Process the field and add to the tag
*
* Note:In the case of coverart MP4 holds all the coverart within individual dataitems all within
* a single covr atom, we will add separate mp4field for each image.
*
* @param tag
* @param header
* @param raw
* @return
* @throws UnsupportedEncodingException
*/
private void createMp4Field(Mp4Tag tag, Mp4BoxHeader header, ByteBuffer raw) throws UnsupportedEncodingException {
// Header with no data #JAUDIOTAGGER-463
if (header.getDataLength() == 0) {
// Just Ignore
} else // Reverse Dns Atom
if (header.getId().equals(Mp4TagReverseDnsField.IDENTIFIER)) {
//
try {
TagField field = new Mp4TagReverseDnsField(header, raw);
tag.addField(field);
} catch (Exception e) {
logger.warning(ErrorMessage.MP4_UNABLE_READ_REVERSE_DNS_FIELD.getMsg(e.getMessage()));
TagField field = new Mp4TagRawBinaryField(header, raw);
tag.addField(field);
}
} else // Normal Parent with Data atom
{
int currentPos = raw.position();
boolean isDataIdentifier = Utils.getString(raw, Mp4BoxHeader.IDENTIFIER_POS, Mp4BoxHeader.IDENTIFIER_LENGTH, "ISO-8859-1").equals(Mp4DataBox.IDENTIFIER);
raw.position(currentPos);
if (isDataIdentifier) {
// Need this to decide what type of Field to create
int type = Utils.getIntBE(raw, Mp4DataBox.TYPE_POS_INCLUDING_HEADER, Mp4DataBox.TYPE_POS_INCLUDING_HEADER + Mp4DataBox.TYPE_LENGTH - 1);
Mp4FieldType fieldType = Mp4FieldType.getFieldType(type);
logger.config("Box Type id:" + header.getId() + ":type:" + fieldType);
// Special handling for some specific identifiers otherwise just base on class id
if (header.getId().equals(Mp4FieldKey.TRACK.getFieldName())) {
TagField field = new Mp4TrackField(header.getId(), raw);
tag.addField(field);
} else if (header.getId().equals(Mp4FieldKey.DISCNUMBER.getFieldName())) {
TagField field = new Mp4DiscNoField(header.getId(), raw);
tag.addField(field);
} else if (header.getId().equals(Mp4FieldKey.GENRE.getFieldName())) {
TagField field = new Mp4GenreField(header.getId(), raw);
tag.addField(field);
} else if (header.getId().equals(Mp4FieldKey.ARTWORK.getFieldName()) || Mp4FieldType.isCoverArtType(fieldType)) {
int processedDataSize = 0;
int imageCount = 0;
// The loop should run for each image (each data atom)
while (processedDataSize < header.getDataLength()) {
// for each subimage (if there are more than one image)
if (imageCount > 0) {
type = Utils.getIntBE(raw, processedDataSize + Mp4DataBox.TYPE_POS_INCLUDING_HEADER, processedDataSize + Mp4DataBox.TYPE_POS_INCLUDING_HEADER + Mp4DataBox.TYPE_LENGTH - 1);
fieldType = Mp4FieldType.getFieldType(type);
}
Mp4TagCoverField field = new Mp4TagCoverField(raw, fieldType);
tag.addField(field);
processedDataSize += field.getDataAndHeaderSize();
imageCount++;
}
} else if (fieldType == Mp4FieldType.TEXT) {
TagField field = new Mp4TagTextField(header.getId(), raw);
tag.addField(field);
} else if (fieldType == Mp4FieldType.IMPLICIT) {
TagField field = new Mp4TagTextNumberField(header.getId(), raw);
tag.addField(field);
} else if (fieldType == Mp4FieldType.INTEGER) {
TagField field = new Mp4TagByteField(header.getId(), raw);
tag.addField(field);
} else {
boolean existingId = false;
for (Mp4FieldKey key : Mp4FieldKey.values()) {
if (key.getFieldName().equals(header.getId())) {
// The parentHeader is a known id but its field type is not one of the expected types so
// this field is invalid. i.e I received a file with the TMPO set to 15 (Oxf) when it should
// be 21 (ox15) so looks like somebody got their decimal and hex numbering confused
// So in this case best to ignore this field and just write a warning
existingId = true;
logger.warning("Known Field:" + header.getId() + " with invalid field type of:" + type + " is ignored");
break;
}
}
// Unknown field id with unknown type so just create as binary
if (!existingId) {
logger.warning("UnKnown Field:" + header.getId() + " with invalid field type of:" + type + " created as binary");
TagField field = new Mp4TagBinaryField(header.getId(), raw);
tag.addField(field);
}
}
} else // Special Cases
{
// copy parent and child as is without modification
if (header.getId().equals(Mp4NonStandardFieldKey.AAPR.getFieldName())) {
TagField field = new Mp4TagRawBinaryField(header, raw);
tag.addField(field);
} else // Default case
{
TagField field = new Mp4TagRawBinaryField(header, raw);
tag.addField(field);
}
}
}
}
use of org.jaudiotagger.tag.mp4.field.Mp4TagCoverField in project MusicDNA by harjot-oberai.
the class Mp4TagCreator method convert.
/**
* Convert tagdata to rawdata ready for writing to file
*
* @param tag
* @param padding TODO padding parameter currently ignored
* @return
* @throws UnsupportedEncodingException
*/
public ByteBuffer convert(Tag tag, int padding) throws UnsupportedEncodingException {
try {
// Add metadata raw content
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Iterator<TagField> it = tag.getFields();
boolean processedArtwork = false;
while (it.hasNext()) {
TagField frame = it.next();
// To ensure order is maintained dont process artwork until iterator hits it.
if (frame instanceof Mp4TagCoverField) {
if (processedArtwork) {
// ignore
} else {
processedArtwork = true;
// Because each artwork image is held within the tag as a separate field, but when
// they are written they are all held under a single covr box we need to do some checks
// and special processing here if we have any artwork image (this code only necessary
// if we have more than 1 but do it anyway even if only have 1 image)
ByteArrayOutputStream covrDataBaos = new ByteArrayOutputStream();
try {
for (TagField artwork : tag.getFields(FieldKey.COVER_ART)) {
covrDataBaos.write(((Mp4TagField) artwork).getRawContentDataOnly());
}
} catch (KeyNotFoundException knfe) {
// This cannot happen
throw new RuntimeException("Unable to find COVERART Key");
}
// Now create the parent Data
byte[] data = covrDataBaos.toByteArray();
baos.write(Utils.getSizeBEInt32(Mp4BoxHeader.HEADER_LENGTH + data.length));
baos.write(Utils.getDefaultBytes(Mp4FieldKey.ARTWORK.getFieldName(), "ISO-8859-1"));
baos.write(data);
}
} else {
baos.write(frame.getRawContent());
}
}
// Wrap into ilst box
ByteArrayOutputStream ilst = new ByteArrayOutputStream();
ilst.write(Utils.getSizeBEInt32(Mp4BoxHeader.HEADER_LENGTH + baos.size()));
ilst.write(Utils.getDefaultBytes(Mp4AtomIdentifier.ILST.getFieldName(), "ISO-8859-1"));
ilst.write(baos.toByteArray());
// Put into ByteBuffer
ByteBuffer buf = ByteBuffer.wrap(ilst.toByteArray());
buf.rewind();
return buf;
} catch (IOException ioe) {
// Should never happen as not writing to file at this point
throw new RuntimeException(ioe);
}
}
Aggregations