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

AACTagReader

public class AACTagReader extends Object

(Omit source code)

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);