Search in sources :

Example 6 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4TrackField method build.

protected void build(ByteBuffer data) throws UnsupportedEncodingException {
    // Data actually contains a 'Data' Box so process data using this
    Mp4BoxHeader header = new Mp4BoxHeader(data);
    Mp4DataBox databox = new Mp4DataBox(header, data);
    dataSize = header.getDataLength();
    numbers = databox.getNumbers();
    // Track number always hold three values, we can discard the first one, the second one is the track no
    // and the third is the total no of tracks so only use if not zero
    StringBuffer sb = new StringBuffer();
    if (numbers != null) {
        if ((numbers.size() > TRACK_NO_INDEX) && (numbers.get(TRACK_NO_INDEX) > 0)) {
            sb.append(numbers.get(TRACK_NO_INDEX));
        }
        if ((numbers.size() > TRACK_TOTAL_INDEX) && (numbers.get(TRACK_TOTAL_INDEX) > 0)) {
            sb.append("/").append(numbers.get(TRACK_TOTAL_INDEX));
        }
    }
    content = sb.toString();
}
Also used : Mp4DataBox(org.jaudiotagger.tag.mp4.atom.Mp4DataBox) Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)

Example 7 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4AtomTree method buildTree.

/**
 * Build a tree of the atoms in the file
 *
 * @param raf
 * @param closeExit false to keep randomfileacces open, only used when randomaccessfile already being used
 * @return
 * @throws java.io.IOException
 * @throws org.jaudiotagger.audio.exceptions.CannotReadException
 */
public DefaultTreeModel buildTree(RandomAccessFile raf, boolean closeExit) throws IOException, CannotReadException {
    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())) {
                // and finish
                if (moovNode != null & mdatNode != null) {
                    logger.warning(ErrorMessage.ADDITIONAL_MOOV_ATOM_AT_END_OF_MP4.getMsg(fc.position() - Mp4BoxHeader.HEADER_LENGTH));
                    break;
                }
                moovNode = newAtom;
                moovHeader = boxHeader;
                long filePosStart = fc.position();
                moovBuffer = ByteBuffer.allocate(boxHeader.getDataLength());
                int bytesRead = fc.read(moovBuffer);
                // If Moov atom is incomplete we are not going to be able to read this file properly
                if (bytesRead < boxHeader.getDataLength()) {
                    String msg = ErrorMessage.ATOM_LENGTH_LARGER_THAN_DATA.getMsg(boxHeader.getId(), boxHeader.getDataLength(), bytesRead);
                    throw new CannotReadException(msg);
                }
                moovBuffer.rewind();
                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 {
        // 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();
        }
    }
}
Also used : Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader) DefaultMutableTreeNode(org.jaudiotagger.utils.tree.DefaultMutableTreeNode) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) FileChannel(java.nio.channels.FileChannel) DefaultTreeModel(org.jaudiotagger.utils.tree.DefaultTreeModel) NullBoxIdException(org.jaudiotagger.audio.exceptions.NullBoxIdException) ByteBuffer(java.nio.ByteBuffer) NullPadding(org.jaudiotagger.audio.mp4.atom.NullPadding)

Example 8 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4TagCoverField method build.

protected void build(ByteBuffer raw) {
    Mp4BoxHeader header = new Mp4BoxHeader(raw);
    dataSize = header.getDataLength();
    dataAndHeaderSize = header.getLength();
    // Skip the version and length fields
    raw.position(raw.position() + Mp4DataBox.PRE_DATA_LENGTH);
    // Read the raw data into byte array
    this.dataBytes = new byte[dataSize - Mp4DataBox.PRE_DATA_LENGTH];
    raw.get(dataBytes, 0, dataBytes.length);
    // Is there room for another atom (remember actually passed all the data so unless Covr is last atom
    // there will be room even though more likely to be for the text top level atom)
    int positionAfterDataAtom = raw.position();
    if (raw.position() + Mp4BoxHeader.HEADER_LENGTH <= raw.limit()) {
        // Is there a following name field (not the norm)
        Mp4BoxHeader nameHeader = new Mp4BoxHeader(raw);
        if (nameHeader.getId().equals(Mp4NameBox.IDENTIFIER)) {
            dataSize += nameHeader.getDataLength();
            dataAndHeaderSize += nameHeader.getLength();
        } else {
            raw.position(positionAfterDataAtom);
        }
    }
// After returning buffers position will be after the end of this atom
}
Also used : Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)

Example 9 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4TagReverseDnsField method build.

protected void build(ByteBuffer data) throws UnsupportedEncodingException {
    // Read mean box, set the issuer and skip over data
    Mp4BoxHeader meanBoxHeader = new Mp4BoxHeader(data);
    Mp4MeanBox meanBox = new Mp4MeanBox(meanBoxHeader, data);
    setIssuer(meanBox.getIssuer());
    data.position(data.position() + meanBoxHeader.getDataLength());
    // Read name box, identify what type of field it is
    Mp4BoxHeader nameBoxHeader = new Mp4BoxHeader(data);
    Mp4NameBox nameBox = new Mp4NameBox(nameBoxHeader, data);
    setDescriptor(nameBox.getName());
    data.position(data.position() + nameBoxHeader.getDataLength());
    // Issue 198:There is not actually a data atom there cannot cant be because no room for one
    if (parentHeader.getDataLength() == meanBoxHeader.getLength() + nameBoxHeader.getLength()) {
        id = IDENTIFIER + ":" + issuer + ":" + descriptor;
        setContent("");
        logger.warning(ErrorMessage.MP4_REVERSE_DNS_FIELD_HAS_NO_DATA.getMsg(id));
    } else // Usual Case
    {
        // Read data box, identify the data
        Mp4BoxHeader dataBoxHeader = new Mp4BoxHeader(data);
        Mp4DataBox dataBox = new Mp4DataBox(dataBoxHeader, data);
        setContent(dataBox.getContent());
        data.position(data.position() + dataBoxHeader.getDataLength());
        // Now calculate the id which in order to be unique needs to use all htree values
        id = IDENTIFIER + ":" + issuer + ":" + descriptor;
    }
}
Also used : Mp4NameBox(org.jaudiotagger.tag.mp4.atom.Mp4NameBox) Mp4MeanBox(org.jaudiotagger.tag.mp4.atom.Mp4MeanBox) Mp4DataBox(org.jaudiotagger.tag.mp4.atom.Mp4DataBox) Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)

Example 10 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4GenreField method build.

protected void build(ByteBuffer data) throws UnsupportedEncodingException {
    // Data actually contains a 'Data' Box so process data using this
    Mp4BoxHeader header = new Mp4BoxHeader(data);
    Mp4DataBox databox = new Mp4DataBox(header, data);
    dataSize = header.getDataLength();
    numbers = databox.getNumbers();
    if (numbers.size() > 0) {
        int genreId = numbers.get(0);
        // Get value, we have to adjust index by one because iTunes labels from one instead of zero
        content = GenreTypes.getInstanceOf().getValueForId(genreId - 1);
        // as null so apps can handle if they wish, but we do display a warning to make them aware.
        if (content == null) {
            logger.warning(ErrorMessage.MP4_GENRE_OUT_OF_RANGE.getMsg(genreId));
        }
    } else {
        logger.warning(ErrorMessage.MP4_NO_GENREID_FOR_GENRE.getMsg(header.getDataLength()));
    }
}
Also used : Mp4DataBox(org.jaudiotagger.tag.mp4.atom.Mp4DataBox) Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)

Aggregations

Mp4BoxHeader (org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)13 Mp4DataBox (org.jaudiotagger.tag.mp4.atom.Mp4DataBox)7 DefaultMutableTreeNode (org.jaudiotagger.utils.tree.DefaultMutableTreeNode)3 ByteBuffer (java.nio.ByteBuffer)2 CannotReadException (org.jaudiotagger.audio.exceptions.CannotReadException)2 NullBoxIdException (org.jaudiotagger.audio.exceptions.NullBoxIdException)2 Mp4MetaBox (org.jaudiotagger.audio.mp4.atom.Mp4MetaBox)2 NullPadding (org.jaudiotagger.audio.mp4.atom.NullPadding)2 FileChannel (java.nio.channels.FileChannel)1 Mp4StcoBox (org.jaudiotagger.audio.mp4.atom.Mp4StcoBox)1 Mp4Tag (org.jaudiotagger.tag.mp4.Mp4Tag)1 Mp4MeanBox (org.jaudiotagger.tag.mp4.atom.Mp4MeanBox)1 Mp4NameBox (org.jaudiotagger.tag.mp4.atom.Mp4NameBox)1 DefaultTreeModel (org.jaudiotagger.utils.tree.DefaultTreeModel)1