IdEst – ID3 Editing and Scripting Tool (split by section):   Section:   Chapter:FastBack: Scripting   Up: Scripting   FastForward: Backups   Contents: Table of ContentsIndex: Concept Index

10.1 Using Scripts to List ID3 Frames

This section illustrates how to use the scripting facility for listing the contents of ID3 tags.

The simplest way to list all frames using a Guile script is:

;; list1.scm -- lists all frames.
(define (idest-main name frames)
  (display name)
  (newline)
  (for-each
   (lambda (frame)
     (display frame)
     (newline))
   frames))

Here is a sample output:

$ idest --script list1.scm track01.scm
track01.mp3
(TIT2 (descr . Title/songname/content description)
      (text . Cor i arbre))
(TRCK (descr . Track number/position in set)
      (text . 1))
(COMM (descr . Comments) (condesc . Bit_Rate)
      (lang . eng) (text . 320))
(TENC (descr . Encoded by) (text . Myencoder 1.0))
(COMM (descr . Comments) (condesc . Sample_Rate)
      (lang . eng) (text . 44100))

As mentioned above, a script can access the command-line arguments. To illustrate this, let’s modify the list1.scm to display only a subset of frames, given as a comma-separated list in the first argument. To do so, we will need a list of requested frames:

(define frame-list '())

The main function consults this list to see whether to display a frame:

(define (idest-main name frames)
  (display name)
  (newline)
  (for-each
   (lambda (frame)
     (if (member (car frame) frame-list)
	 (begin
	   (display frame)
	   (newline))))
   frames))

Finally, the following code initializes frame-list from the first argument and removes that argument from the list seen by idest. Note that the 0th argument is the name of the script itself, and it should not be modified.

(let ((cmd (command-line)))
  (cond
   ((< (length cmd) 3)
    (error "usage: idest -S list2 FRAME-LIST FILE...")
    (exit 1))
   (else
    (set! frame-list (string-split (list-ref cmd 1) #\,))
    (set-program-arguments (cons (car cmd)
                           (list-tail cmd 2))))))

The full script text is then:

;; list2.scm -- lists only requested frames.
(define frame-list '())

(define (idest-main name frames)
  (display name)
  (newline)
  (for-each
   (lambda (frame)
     (if (member (car frame) frame-list)
	 (begin
	   (display frame)
	   (newline))))
   frames))

(let ((cmd (command-line)))
  (cond
   ((< (length cmd) 3)
    (error "usage: idest -S list2 FRAME-LIST FILE...")
    (exit 1))
   (else
    (set! frame-list (string-split (list-ref cmd 1) #\,))
    (set-program-arguments (cons (car cmd)
                                 (list-tail cmd 2))))))

Sample usage:

$ idest --script list2 TIT2,TENC track01.scm
(TIT2 (descr . Title/songname/content description)
      (text . Cor i arbre))
(TENC (descr . Encoded by) (text . Myencoder 1.0))

A more elaborate example will print, for each input file, its name, followed by the title, artist name and year, as shown in this sample output:

$ idest -S shortlist *.mp3
dnr.mp3: Diamonds & Rust by Joan Baez, 1975
ams.mp3: Amsterdam, by Jacques Brel, 1968

To implement this, we would need a function that returns the value of a given frame from the frame list. Remember, that the latter is a list of pairs, so the task is achieved easily by using the assoc-ref function:

(define (get-frame code frames)
  (or (assoc-ref
       (or (assoc-ref frames code) '())
       'text)
      "unknown"))

The inner assoc-ref selects a requested frame. An empty list is returned if such a frame is not found. The outer assoc-ref selects the ‘text’ property.

Now, we define the main function:

(define (idest-main name frames)
  (format #t "~A: ~A by ~A, ~A~%"
	  name
	  (get-frame "TIT2" frames)   ; Title
	  (get-frame "TPE1" frames)   ; Artist
	  (get-frame "TDRC" frames))) ; Year

IdEst – ID3 Editing and Scripting Tool (split by section):   Section:   Chapter:FastBack: Scripting   Up: Scripting   FastForward: Backups   Contents: Table of ContentsIndex: Concept Index