ADC Home > Reference Library > Technical Q&As > QuickTime > Movie Basics >

Using QuickTime to access MP3 ID3 Tags


Q: I know QuickTime allows access to ID3 tags in MP3 music files, but I can't figure out how to access this capability. I really need the Song Title, Album Title, Artist, Year, and Track Number.

A: The QuickTime MP3 Movie Importer recognizes ID3 tags and turns them into movie annotations stored as Movie User Data. You can import an .mp3 file as a Movie, then access this user data by calling Movie Toolbox APIs such as GetMovieUserData, GetNextUserDataType and GetUserDataText.

The code snippet in Listing 1 takes a user data list, and outputs user data items to the console. Each user data type has a unique identifier:

kUserDataTextFullName = FOUR_CHAR_CODE('©nam')
kUserDataTextArtist = FOUR_CHAR_CODE('©ART')
kUserDataTextAlbum = FOUR_CHAR_CODE('©alb')

etc.

See Movies.h for the list of interesting user data types.

Movie Tracks and Media can also have their own user data lists. These lists can be accessed by calling GetTrackUserData or GetMediaUserData respectively.

const UInt8 kUserDataIsText = 0xA9; // the copyright symbol

OSErr PrintUserData(UserData inUserData)
{
  OSType udType;
  short count, i;
  char nul = 0;
  Handle hData = NULL;
  Ptr p;

  OSErr err = noErr;

  hData = NewHandle(0);
  udType = GetNextUserDataType(inUserData, 0);
  if(0 != udType) {
    printf("\nMeta-data:\n");

    do {
      count = CountUserDataType(inUserData, udType);
      for(i = 1; i <= count; i++) {
        if((udType>>24) == kUserDataIsText) {

          // if the first letter of udType is 0xA9 (the copyright symbol),
          // then use GetUserDataText instead of GetUserData
          // See Movies.h for a list of interesting user data types
          err = GetUserDataText(inUserData, hData, udType, i, langEnglish);
          if (err) goto bail;

          // null-terminate the string in the handle
          PtrAndHand(&nul, hData, 1);

          // turn any CRs into spaces
          p = *hData;
          while(*p) {
            if (*p == kReturnCharCode) *p = ' ';
            p++;
          };

          HLock(hData);
          printf("  %c%c%c%c: %s\n", (char)(udType>>24),
                (char)(udType>>16),
                (char)(udType>>8),
                (char)udType, *hData);
          HUnlock(hData);

        } else {

          err = GetUserData(inUserData, hData, udType, i);
          if (err) goto bail;

          printf("  %c%c%c%c: [%d bytes]\n",
                (char)(udType>>24),
                (char)(udType>>16),
                (char)(udType>>8),
                (char)udType, GetHandleSize(hData));
        }
      }

      udType = GetNextUserDataType(inUserData, udType);

    } while(0 != udType);
  }

bail:
  printf("\n");

  // NOTE: don't dispose UserData you did not allocate
  DisposeHandle(hData);

  return err;
}

Listing 1. PrintUserData


{
  UserData userData = 0;
  OSErr err;

  ...

  userData = GetMovieUserData(theMovie);
  if (userData) {
    err = PrintUserData(userData);
  }

  ...
}                  

Listing 2. Snippet calling Listing 1

Example output produced by Listing 1 using an .mp3 file:

Meta-data:

    ©nam: allthewayhome.mp3

    ©ART: Spinal Tap

    ©alb: Break Like The Wind

    ©day: 1992

    ©trk: 14/14

    ©cmt: It goes to 11


References:

Working with Movie UserData

Track Names - Ice Floe #2


[Apr 08 2002]


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.