use of org.jaudiotagger.audio.mp4.atom.Mp4MetaBox in project MusicDNA by harjot-oberai.
the class Mp4AtomTree method buildChildrenOfNode.
/**
*
* @param moovBuffer
* @param parentNode
* @throws IOException
* @throws CannotReadException
*/
public void buildChildrenOfNode(ByteBuffer moovBuffer, DefaultMutableTreeNode parentNode) throws IOException, CannotReadException {
Mp4BoxHeader boxHeader;
//Preprocessing for nodes that contain data before their children atoms
Mp4BoxHeader parentBoxHeader = (Mp4BoxHeader) parentNode.getUserObject();
//We set the buffers position back to this after processing the children
int justAfterHeaderPos = moovBuffer.position();
//Preprocessing for meta that normally contains 4 data bytes, but doesn'timer where found under track or tags atom
if (parentBoxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName())) {
Mp4MetaBox meta = new Mp4MetaBox(parentBoxHeader, moovBuffer);
meta.processData();
try {
boxHeader = new Mp4BoxHeader(moovBuffer);
} catch (NullBoxIdException nbe) {
//It might be that the meta box didn'timer actually have any additional data after it so we adjust the buffer
//to be immediately after metabox and code can retry
moovBuffer.position(moovBuffer.position() - Mp4MetaBox.FLAGS_LENGTH);
} finally {
//Skip back last header cos this was only a test
moovBuffer.position(moovBuffer.position() - Mp4BoxHeader.HEADER_LENGTH);
}
}
//Defines where to start looking for the first child node
int startPos = moovBuffer.position();
while (moovBuffer.position() < ((startPos + parentBoxHeader.getDataLength()) - Mp4BoxHeader.HEADER_LENGTH)) {
boxHeader = new Mp4BoxHeader(moovBuffer);
if (boxHeader != null) {
boxHeader.setFilePos(moovHeader.getFilePos() + moovBuffer.position());
logger.finest("Atom " + boxHeader.getId() + " @ " + boxHeader.getFilePos() + " of size:" + boxHeader.getLength() + " ,ends @ " + (boxHeader.getFilePos() + boxHeader.getLength()));
DefaultMutableTreeNode newAtom = new DefaultMutableTreeNode(boxHeader);
parentNode.add(newAtom);
if (boxHeader.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) {
udtaNode = newAtom;
} else //only interested in metaNode that is child of udta node
if (boxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName()) && parentBoxHeader.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) {
metaNode = newAtom;
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.HDLR.getFieldName()) && parentBoxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName())) {
hdlrWithinMetaNode = newAtom;
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.HDLR.getFieldName())) {
hdlrWithinMdiaNode = newAtom;
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.TAGS.getFieldName())) {
tagsNode = newAtom;
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.STCO.getFieldName())) {
if (stco == null) {
stco = new Mp4StcoBox(boxHeader, moovBuffer);
stcoNode = newAtom;
}
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.ILST.getFieldName())) {
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentNode.getParent();
if (parent != null) {
Mp4BoxHeader parentsParent = (Mp4BoxHeader) (parent).getUserObject();
if (parentsParent != null) {
if (parentBoxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName()) && parentsParent.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) {
ilstNode = newAtom;
}
}
}
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.FREE.getFieldName())) {
//Might be multiple in different locations
freeNodes.add(newAtom);
} else if (boxHeader.getId().equals(Mp4AtomIdentifier.TRAK.getFieldName())) {
//Might be multiple in different locations, although only one should be audio track
trakNodes.add(newAtom);
}
//For these atoms iterate down to build their children
if ((boxHeader.getId().equals(Mp4AtomIdentifier.TRAK.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.MDIA.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.MINF.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.STBL.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.ILST.getFieldName()))) {
buildChildrenOfNode(moovBuffer, newAtom);
}
//Now adjust buffer for the next atom header at this level
moovBuffer.position(moovBuffer.position() + boxHeader.getDataLength());
}
}
moovBuffer.position(justAfterHeaderPos);
}
use of org.jaudiotagger.audio.mp4.atom.Mp4MetaBox in project MusicDNA by harjot-oberai.
the class Mp4TagReader method read.
/*
* The metadata is stored in the box under the hierachy moov.udta.meta.ilst
*
* There are gaps between these boxes
*/
public Mp4Tag read(RandomAccessFile raf) throws CannotReadException, IOException {
Mp4Tag tag = new Mp4Tag();
//Get to the facts everything we are interested in is within the moov box, so just load data from file
//once so no more file I/O needed
Mp4BoxHeader moovHeader = Mp4BoxHeader.seekWithinLevel(raf, Mp4AtomIdentifier.MOOV.getFieldName());
if (moovHeader == null) {
throw new CannotReadException(ErrorMessage.MP4_FILE_NOT_CONTAINER.getMsg());
}
ByteBuffer moovBuffer = ByteBuffer.allocate(moovHeader.getLength() - Mp4BoxHeader.HEADER_LENGTH);
raf.getChannel().read(moovBuffer);
moovBuffer.rewind();
//Level 2-Searching for "udta" within "moov"
Mp4BoxHeader boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.UDTA.getFieldName());
if (boxHeader != null) {
//Level 3-Searching for "meta" within udta
boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.META.getFieldName());
if (boxHeader == null) {
logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
return tag;
}
Mp4MetaBox meta = new Mp4MetaBox(boxHeader, moovBuffer);
meta.processData();
//Level 4- Search for "ilst" within meta
boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.ILST.getFieldName());
//This file does not actually contain a tag
if (boxHeader == null) {
logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
return tag;
}
} else {
//Level 2-Searching for "meta" not within udta
boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.META.getFieldName());
if (boxHeader == null) {
logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
return tag;
}
Mp4MetaBox meta = new Mp4MetaBox(boxHeader, moovBuffer);
meta.processData();
//Level 3- Search for "ilst" within meta
boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.ILST.getFieldName());
//This file does not actually contain a tag
if (boxHeader == null) {
logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
return tag;
}
}
//Size of metadata (exclude the size of the ilst parentHeader), take a slice starting at
//metadata children to make things safer
int length = boxHeader.getLength() - Mp4BoxHeader.HEADER_LENGTH;
ByteBuffer metadataBuffer = moovBuffer.slice();
//Datalength is longer are there boxes after ilst at this level?
logger.config("headerlengthsays:" + length + "datalength:" + metadataBuffer.limit());
int read = 0;
logger.config("Started to read metadata fields at position is in metadata buffer:" + metadataBuffer.position());
while (read < length) {
//Read the boxHeader
boxHeader.update(metadataBuffer);
//Create the corresponding datafield from the id, and slice the buffer so position of main buffer
//wont get affected
logger.config("Next position is at:" + metadataBuffer.position());
createMp4Field(tag, boxHeader, metadataBuffer.slice());
//Move position in buffer to the start of the next parentHeader
metadataBuffer.position(metadataBuffer.position() + boxHeader.getDataLength());
read += boxHeader.getLength();
}
return tag;
}
Aggregations