FileDocCategorySizeDatePackage
AACTagReader.javaAPI DocExample7641Wed Nov 10 12:51:22 GMT 2004com.oreilly.qtjnotebook.ch07

AACTagReader

public class AACTagReader extends Object

Fields Summary
static final int
kUserDataTextAlbum
static final int
kUserDataTextArtist
static final int
kUserDataTextCreationDate
static final int
kUserDataTextFullName
private static final Object[]
TAG_NAMES
private static final HashMap
TAG_MAP
Constructors Summary
public AACTagReader()

        try {
            QTSessionCheck.check();
            QTFile f = QTFile.standardGetFilePreview (null);
            OpenMovieFile omf = OpenMovieFile.asRead(f);
            Movie movie = Movie.fromFile (omf);
            // get user data
            UserData userData = movie.getUserData();
            dumpTagsFromUserData(userData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
Methods Summary
protected voiddumpTagsFromUserData(UserData userData)

        int metaFCC = QTUtils.toOSType("meta");
        QTHandle metaHandle = userData.getData (metaFCC, 1);
        System.out.println ("Found meta");
        byte[] metaBytes = metaHandle.getBytes();

        // locate the "ilst" pseudo-atom, ignoring first 4 bytes
        int ilstFCC = QTUtils.toOSType("ilst");
        // System.out.println ("Looking for ilst, " + FCC_ilst);
        PseudoAtomPointer ilst = findPseudoAtom (metaBytes, 4, ilstFCC);
        // System.out.println ("Found ilst at " + ilst.offset);

        // iterate over the pseudo-atoms inside the "ilst"
        // building lists of tags and values from which we'll
        // create arrays for the DefaultTableModel constructor
        int off = ilst.offset + 8;
        ArrayList foundTags = new ArrayList (TAG_NAMES.length);
        ArrayList foundValues = new ArrayList (TAG_NAMES.length);
        while (off < metaBytes.length) {
            PseudoAtomPointer atom = findPseudoAtom (metaBytes, off, -1);
            /*
            System.out.println ("Found " +
                                QTUtils.fromOSType (atom.type) +
                                " atom at " + atom.offset);
            */
            String tagName = (String) TAG_MAP.get (new Integer(atom.type));
            if (tagName != null) {
                // if we match a type, read everything after byte 24
                // which skips size, type, size, 'data', 8 junk bytes
                byte[] valueBytes = new byte [atom.atomSize - 24];
                System.arraycopy (metaBytes,
                                  atom.offset+24,
                                  valueBytes,
                                  0,
                                  valueBytes.length);
                // note: this approach is stupid about UTF-8'ed data
                String value = new String (valueBytes);
                System.out.println (tagName + ": " + value);
            } // if tagName != null
            off = atom.offset + atom.atomSize;
        }

    
private com.oreilly.qtjnotebook.ch07.AACTagReader$PseudoAtomPointerfindPseudoAtom(byte[] bytes, int start, int type)
find the given type in the byte array, starting at the start position. Returns the offset within the bye array that begins this pseudo-atom. a helper method to populateFromMetaAtom().

param
bytes byte array to search
param
start offset to start at
param
type type to search for. if -1, returns first atom with a plausible size

        // read size, then type
        // if size is bogus, forget it, increment offset, and try again
        int off = start;
        boolean found = false;
        while ((! found) &&
               (off < bytes.length-8)) {
            // read 32 bits of atom size
            // use BigInteger to convert bytes to long
            // (instead of signed int)
            byte sizeBytes[] = new byte[4];
            System.arraycopy (bytes, off, sizeBytes, 0, 4);
            BigInteger atomSizeBI = new BigInteger (sizeBytes);
            long atomSize = atomSizeBI.longValue();

            // don't bother if the size would take us beyond end of
            // array, or is impossibly small
            if ((atomSize > 7) &&
                (off + atomSize <= bytes.length)) {
                byte[] typeBytes = new byte[4];
                System.arraycopy (bytes, off+4, typeBytes, 0, 4);
                int aType = QTUtils.toOSType (new String (typeBytes));

                if ((type == aType) ||
                    (type == -1))
                    return new PseudoAtomPointer (off, (int) atomSize, aType);
                else
                    off += atomSize;
                                    
            } else {
                System.out.println ("bogus atom size " + atomSize);
                // well, how did this happen?  increment off and try again
                off++;
            }
        } // while
        return null;
    
public static voidmain(java.lang.String[] args)

     
        for (int i=0; i<TAG_NAMES.length; i++) {
            TAG_MAP.put (TAG_NAMES[i][0],
                         TAG_NAMES[i][1]);
        }
    
        new AACTagReader();
        System.exit(0);