On this page:
4.1 Reading metadata
id3-tags
tags-valid?
4.2 Common tag fields
tags-title
tags-album
tags-artist
tags-comment
tags-genre
tags-year
tags-track
tags-composer
tags-album-artist
tags-disc-number
4.3 Audio properties
tags-length
tags-sample-rate
tags-bit-rate
tags-channels
4.4 Generic properties
tags-keys
tags-ref
4.5 Embedded pictures
tags-picture
tags-picture->kind
tags-picture->mimetype
tags-picture->size
tags-picture->ext
tags-picture->bitmap
tags-picture->file
4.6 Picture values
id3-picture-mimetype
id3-picture-kind
id3-picture-size
id3-picture-bytes
4.7 Converting to a hash
tags->hash
4.8 Example
4.9 Implementation notes
9.1

4 TagLib Metadata🔗ℹ

Hans Dijkema <hans@dijkewijk.nl>

 (require racket-audio/taglib) package: racket-audio

The racket-audio/taglib module provides the high level metadata reader used by the audio package. It wraps the lower level TagLib FFI module and presents a small, read-only Racket API for common tags, audio properties, generic properties, and embedded cover art.

Calling id3-tags opens the file through TagLib, copies the values that are needed on the Racket side, reads the optional embedded picture, frees the native TagLib objects, and returns an opaque tag handle. The handle is therefore a snapshot of the metadata at the time it was read. It does not keep the media file or the native TagLib handle open.

The name id3-tags is historical. The module uses TagLib to open the file, so the usable file types are the file types supported by the TagLib library available at run time. This module is not a tag editor; it only reads metadata.

4.1 Reading metadata🔗ℹ

procedure

(id3-tags file)  any/c

  file : path-string?
Reads metadata from file and returns an opaque tag handle. The argument may be a path or a string. On Windows, the implementation retries with the wide-character TagLib open function when the normal open function does not produce a valid TagLib file.

The returned handle is passed to the other procedures in this module. If the file cannot be opened, id3-tags still returns a handle, but tags-valid? returns #f. Other accessors then return their default values, such as "", -1, '(), or #f.

procedure

(tags-valid? tags)  boolean?

  tags : any/c
Returns #t when id3-tags successfully opened the file and TagLib reported it as valid.

(define tags (id3-tags "song.mp3"))
 
(when (tags-valid? tags)
  (printf "~a - ~a\n" (tags-artist tags) (tags-title tags)))

4.2 Common tag fields🔗ℹ

procedure

(tags-title tags)  string?

  tags : any/c

procedure

(tags-album tags)  string?

  tags : any/c

procedure

(tags-artist tags)  string?

  tags : any/c

procedure

(tags-comment tags)  string?

  tags : any/c

procedure

(tags-genre tags)  string?

  tags : any/c
Return the common textual fields from the TagLib tag interface. Missing fields are returned as the empty string.

procedure

(tags-year tags)  integer?

  tags : any/c

procedure

(tags-track tags)  integer?

  tags : any/c
Return the year and track number from the common TagLib tag interface. Missing numeric values are returned as -1.

procedure

(tags-composer tags)  (or/c string? (listof string?))

  tags : any/c

procedure

(tags-album-artist tags)  (or/c string? (listof string?))

  tags : any/c

procedure

(tags-disc-number tags)  (or/c number? #f)

  tags : any/c
Return selected values from the generic TagLib property store. The composer is read from the lower-case 'composer key, the album artist from 'albumartist, and the disc number from 'discnumber.

Composer and album artist return a list of strings when the property is present and the empty string when it is missing. The disc number is parsed from the first property value and defaults to -1. If the stored value cannot be parsed as a number, the result may be #f. Use tags-keys and tags-ref for direct access to the complete generic property store.

4.3 Audio properties🔗ℹ

procedure

(tags-length tags)  integer?

  tags : any/c

procedure

(tags-sample-rate tags)  integer?

  tags : any/c

procedure

(tags-bit-rate tags)  integer?

  tags : any/c

procedure

(tags-channels tags)  integer?

  tags : any/c
Return audio properties reported by TagLib: length in seconds, sample rate in Hz, bit rate in kbit/s, and number of channels. Missing values are returned as -1.

4.4 Generic properties🔗ℹ

procedure

(tags-keys tags)  (listof symbol?)

  tags : any/c
Returns the generic TagLib property keys found in the file. Keys are lower-cased and converted to symbols.

procedure

(tags-ref tags key)  (or/c (listof string?) #f)

  tags : any/c
  key : symbol?
Returns the list of values associated with key, or #f when the property was not found. Use lower-case symbol keys, matching the values returned by tags-keys.

(for ([key (in-list (tags-keys tags))])
  (printf "~a: ~s\n" key (tags-ref tags key)))

Generic properties may contain multiple values for a single key. The API keeps those values as lists instead of joining them into one string.

4.5 Embedded pictures🔗ℹ

The module represents embedded artwork as an opaque picture value. The picture value is returned by tags-picture and can be inspected with the picture procedures documented below. When no picture is available, the picture-related procedures return #f.

procedure

(tags-picture tags)  (or/c any/c #f)

  tags : any/c
Returns the embedded picture value, or #f when the file has no picture that the underlying FFI layer could read.

procedure

(tags-picture->kind tags)  (or/c integer? #f)

  tags : any/c

procedure

(tags-picture->mimetype tags)  (or/c string? #f)

  tags : any/c

procedure

(tags-picture->size tags)  (or/c integer? #f)

  tags : any/c

procedure

(tags-picture->ext tags)  (or/c symbol? #f)

  tags : any/c
Return selected information about the embedded picture. The kind is the numeric picture type reported by the FFI layer. The MIME type is the stored MIME type, such as "image/jpeg" or "image/png". The size is the number of bytes in the embedded image. The extension helper returns 'jpg, 'png, or #f when the MIME type is not recognized.

procedure

(tags-picture->bitmap tags)  (or/c (is-a?/c bitmap%) #f)

  tags : any/c
Reads the embedded picture bytes with read-bitmap and returns a bitmap% object. If there is no embedded picture, the result is #f.

procedure

(tags-picture->file tags path)  boolean?

  tags : any/c
  path : path-string?
Writes the embedded picture bytes to path in binary mode, replacing an existing file. The procedure returns #t when a picture was written and #f when the tag handle has no picture. The file name is not adjusted automatically; use tags-picture->ext when the caller wants to choose an extension from the MIME type.

(define ext (tags-picture->ext tags))
 
(when ext
  (tags-picture->file tags
                      (format "cover.~a" ext)))

4.6 Picture values🔗ℹ

procedure

(id3-picture-mimetype picture)  string?

  picture : any/c

procedure

(id3-picture-kind picture)  integer?

  picture : any/c

procedure

(id3-picture-size picture)  integer?

  picture : any/c

procedure

(id3-picture-bytes picture)  bytes?

  picture : any/c
Access the fields of a picture value returned by tags-picture. These procedures are useful when the caller wants to process the image bytes directly instead of converting them to a bitmap or writing them to a file.

4.7 Converting to a hash🔗ℹ

procedure

(tags->hash tags)  hash?

  tags : any/c
Returns a mutable hash containing the core values copied from the tag handle. The hash contains the keys 'valid?, 'title, 'album, 'artist, 'comment, 'composer, 'genre, 'year, 'track, 'length, 'sample-rate, 'bit-rate, 'channels, 'picture, and 'keys.

The hash is intended as a convenient snapshot for application code. Generic property values are not expanded into the hash; use tags-ref for those values.

4.8 Example🔗ℹ

(define tags (id3-tags "track.flac"))
 
(cond
  [(not (tags-valid? tags))
   (printf "No readable tags\n")]
  [else
   (printf "Title:  ~a\n" (tags-title tags))
   (printf "Artist: ~a\n" (tags-artist tags))
   (printf "Album:  ~a\n" (tags-album tags))
   (printf "Length: ~a seconds\n" (tags-length tags))
 
   (when (tags-picture tags)
     (define ext (or (tags-picture->ext tags) 'bin))
     (tags-picture->file tags (format "cover.~a" ext)))])

4.9 Implementation notes🔗ℹ

This chapter documents the public "taglib.rkt" layer. The native TagLib calls are delegated to "taglib-ffi.rkt", but callers normally should not use that lower level module directly.

The tag handle is implemented as a small Racket object with a private dispatch procedure. The native TagLib file is not stored in the handle. This keeps the public API simple and prevents native resources from leaking into application code.

The implementation normalizes generic property names by lower-casing TagLib property keys and converting them to symbols. Values remain lists of strings because TagLib properties may contain multiple values for one key.