Audio file info

You know how the Get Info window for an audio file displays the running time of the file?

Audio Get Info

I want to access that information from the command line, and I’ve found two ways to get at it.

First, there’s the afinfo command. There’s not much to it—no options to remember and just a single-line description in the man page:

Audio File Info prints out information about an audio file to stdout

Apple didn’t even bother to put a period at the end of the sentence.

Here’s how you run it,

afinfo b042b38b.m4a

and here’s the kind of output it produces

File:           b042b38b.m4a
File type ID:   m4af
Num Tracks:     1
Data format:     2 ch,  44100 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
Channel layout: Stereo (L R)
estimated duration: 7209.980227 sec
audio bytes: 85714997
audio packets: 310510
bit rate: 95106 bits per second
packet size upper bound: 956
maximum packet size: 956
audio data file offset: 1302118
audio 317960128 valid frames + 2112 priming + 0 remainder = 317962240
format list:
[ 0] format:      2 ch,  44100 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
Channel layout: Stereo (L R)

I can’t help but smirk at an “estimated duration” that’s reported to the millionth of a second.

Because there are no options to allow you to limit the output to just one field, you have to filter out all the dreck on your own. To get just the duration, awk is handy. This command,

afinfo b042b38b.m4a | awk '/duration/{print $3}'

will print just what I want: 7209.980227.

A better command, though is mdls, part of the suite of md* commands that do Spotlighty things with file metadata. This one lists (ls) the metadata (md) of the file given to it on the command line. To get all the metadata at once, run

mdls b042b38b.m4a

To restrict the output to just one piece of information, use the -name option1 followed by the name of the attribute. For duration of an audio file, that name is kMDItemDurationSeconds. Thus,

mdls -name kMDItemDurationSeconds b042b38b.m4a


kMDItemDurationSeconds = 7209.98022675737

Now we see why the afinfo result is considered an estimate. This gives the duration to the hundred-billionth ([10^{-11}]) of a second.

Since we already know the attribute name, it’s kind of silly to print it out as part of the answer. The -raw option will give us just the number:

mdls -name kMDItemDurationSeconds -raw b042b38b.m4a

And when I say “just the number,” I mean it. There’s no newline after it.

Of the two, mdls is the better command to learn, and not just because you can restrict its output to just one piece of metadata. It’s the more general command, able to extract all the information you see in the Get Info window, and it works on every kind of file, not just audio files. The downside of mdls is that you’ll usually have to run it without -name to find the name of the attribute you want. But once you know the name, it’s easy to automate the process. For example, adding

alias duration='mdls -name kMDItemDurationSeconds -raw'

to your .bashrc file will give you a quick and easily remembered command for finding the duration of an audio file.

Irrelevant anecdote on significant digits
When I was in graduate school, I took a class in advanced reinforced concrete design from Mete Sozen, an excellent engineer and an excellent teacher. On the first day of class, he assigned a review problem in which we were to determine the cross-sectional area of steel needed to reinforce a simple concrete beam—the sort of thing that had been covered in our introductory r/c design class. We turned the homework in on the second day of class, and at the beginning of the third class, he handed the graded problems back to us and went to the blackboard.

“Someone,” Sozen said, “gave this answer,” and he wrote a number on the board that had three digits to the right of the decimal point. In other words, someone had handed in an answer with the steel area given to the thousandth of a square inch—far more precision than is warranted, or even possible, in reinforced concrete.

“Do you know what this answer means to me?” he asked, twirling a piece of chalk in his fingers.

We waited.

“It means shit!” he said, attacking the board with the chalk and repeatedly crossing out the number.

I was not the person who gave the overly precise answer, partly because I knew it wasn’t appropriate and partly because I’d been tipped off to this by a friend who’d had the class before me. Sozen did this every year—possibly moderating his language if there were women in the class. It was his way of impressing on us a sense of proportion and the limitations of our knowledge. It worked.

A few days later, my friend passed Sozen in the hall and said “I heard you put on a good show the other day.” Sozen smiled, winked, and kept walking.

  1. Yes, that’s just one dash; Apple doesn’t care about other people’s conventions for command line options.