Fields Summary |
---|
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | rootNode |
private org.jaudiotagger.utils.tree.DefaultTreeModel | dataTree |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | moovNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | mdatNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | stcoNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | ilstNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | metaNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | tagsNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | udtaNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | hdlrWithinMdiaNode |
private org.jaudiotagger.utils.tree.DefaultMutableTreeNode | hdlrWithinMetaNode |
private List | freeNodes |
private List | mdatNodes |
private List | trakNodes |
private org.jaudiotagger.audio.mp4.atom.Mp4StcoBox | stco |
private ByteBuffer | moovBuffer |
private org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader | moovHeader |
public static Logger | logger |
Methods Summary |
---|
public void | buildChildrenOfNode(java.nio.ByteBuffer moovBuffer, org.jaudiotagger.utils.tree.DefaultMutableTreeNode parentNode)
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't 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't 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;
}
//only interested in metaNode that is child of udta node
else 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);
|
public org.jaudiotagger.utils.tree.DefaultTreeModel | buildTree(java.io.RandomAccessFile raf, boolean closeExit)Build a tree of the atoms in the file
FileChannel fc = null;
try
{
fc = raf.getChannel();
//make sure at start of file
fc.position(0);
//Build up map of nodes
rootNode = new DefaultMutableTreeNode();
dataTree = new DefaultTreeModel(rootNode);
//Iterate though all the top level Nodes
ByteBuffer headerBuffer = ByteBuffer.allocate(Mp4BoxHeader.HEADER_LENGTH);
while (fc.position() < fc.size())
{
Mp4BoxHeader boxHeader = new Mp4BoxHeader();
headerBuffer.clear();
fc.read(headerBuffer);
headerBuffer.rewind();
try
{
boxHeader.update(headerBuffer);
}
catch(NullBoxIdException ne)
{
//If we only get this error after all the expected data has been found we allow it
if(moovNode!=null&mdatNode!=null)
{
NullPadding np = new NullPadding(fc.position() - Mp4BoxHeader.HEADER_LENGTH,fc.size());
DefaultMutableTreeNode trailingPaddingNode = new DefaultMutableTreeNode(np);
rootNode.add(trailingPaddingNode);
logger.warning(ErrorMessage.NULL_PADDING_FOUND_AT_END_OF_MP4.getMsg(np.getFilePos()));
break;
}
else
{
//File appears invalid
throw ne;
}
}
boxHeader.setFilePos(fc.position() - Mp4BoxHeader.HEADER_LENGTH);
DefaultMutableTreeNode newAtom = new DefaultMutableTreeNode(boxHeader);
//Go down moov
if (boxHeader.getId().equals(Mp4AtomIdentifier.MOOV.getFieldName()))
{
moovNode = newAtom;
moovHeader = boxHeader;
long filePosStart = fc.position();
moovBuffer = ByteBuffer.allocate(boxHeader.getDataLength());
fc.read(moovBuffer);
moovBuffer.rewind();
/*Maybe needed but dont have test case yet
if(filePosStart + boxHeader.getDataLength() > fc.size())
{
throw new CannotReadException("The atom states its datalength to be "+boxHeader.getDataLength()
+ "but there are only "+fc.size()+"bytes in the file and already at position "+filePosStart);
}
*/
buildChildrenOfNode(moovBuffer, newAtom);
fc.position(filePosStart);
}
else if (boxHeader.getId().equals(Mp4AtomIdentifier.FREE.getFieldName()))
{
//Might be multiple in different locations
freeNodes.add(newAtom);
}
else if (boxHeader.getId().equals(Mp4AtomIdentifier.MDAT.getFieldName()))
{
//mdatNode always points to the last mDatNode, normally there is just one mdatnode but do have
//a valid example of multiple mdatnode
//if(mdatNode!=null)
//{
// throw new CannotReadException(ErrorMessage.MP4_FILE_CONTAINS_MULTIPLE_DATA_ATOMS.getMsg());
//}
mdatNode = newAtom;
mdatNodes.add(newAtom);
}
rootNode.add(newAtom);
fc.position(fc.position() + boxHeader.getDataLength());
}
return dataTree;
}
finally
{
//If we cant find the audio then we cannot modify this file so better to throw exception
//now rather than later when try and write to it.
if(mdatNode==null)
{
throw new CannotReadException(ErrorMessage.MP4_CANNOT_FIND_AUDIO.getMsg());
}
if (closeExit)
{
fc.close();
}
}
|
public org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader | getBoxHeader(org.jaudiotagger.utils.tree.DefaultMutableTreeNode node)
if (node == null)
{
return null;
}
return (Mp4BoxHeader) node.getUserObject();
|
public org.jaudiotagger.utils.tree.DefaultTreeModel | getDataTree()
return dataTree;
|
public java.util.List | getFreeNodes()
return freeNodes;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getHdlrWithinMdiaNode()
return hdlrWithinMdiaNode;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getHdlrWithinMetaNode()
return hdlrWithinMetaNode;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getIlstNode()
return ilstNode;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getMdatNode()
return mdatNode;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getMetaNode()
return metaNode;
|
public java.nio.ByteBuffer | getMoovBuffer()
return moovBuffer;
|
public org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader | getMoovHeader()
return moovHeader;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getMoovNode()
return moovNode;
|
public org.jaudiotagger.audio.mp4.atom.Mp4StcoBox | getStco()
return stco;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getStcoNode()
return stcoNode;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getTagsNode()
return tagsNode;
|
public java.util.List | getTrakNodes()
return trakNodes;
|
public org.jaudiotagger.utils.tree.DefaultMutableTreeNode | getUdtaNode()
return udtaNode;
|
public void | printAtomTree()Display atom tree
Enumeration<DefaultMutableTreeNode> e = rootNode.preorderEnumeration();
DefaultMutableTreeNode nextNode;
while (e.hasMoreElements())
{
nextNode = e.nextElement();
Mp4BoxHeader header = (Mp4BoxHeader) nextNode.getUserObject();
if (header != null)
{
String tabbing = "";
for (int i = 1; i < nextNode.getLevel(); i++)
{
tabbing += "\t";
}
if(header instanceof NullPadding)
{
System.out.println(tabbing + "Null pad " + " @ " + header.getFilePos() + " of size:" + header.getLength() + " ,ends @ " + (header.getFilePos() + header.getLength()));
}
else
{
System.out.println(tabbing + "Atom " + header.getId() + " @ " + header.getFilePos() + " of size:" + header.getLength() + " ,ends @ " + (header.getFilePos() + header.getLength()));
}
}
}
|