Given that the m4a format is merely a container, and can contain music encoded with a lossy (AAC) or lossless (ALAC) codec, is there a simple way to determine which codec was used for a given file?
4 Answers
When I use the file
command on an .m4a file, I get back a generic response of "ISO Media, Apple iTunes ALAC/AAC-LC (.M4A) Audio" for both AAC and ALAC files. I can think of two other approaches off the top of my head that don't require either the heavy hand of iTunes or installing new software :
Open the audio file in question with QuickTime Player. Select "Show Movie Inspector" from the 'Window' menu (or press ⌘-i) to see the file's size, data rate, and the codec used in its creation.
Use the
afinfo
(audio file info) command in Terminal.app to get a more information than QuickTime Player provides. Here's some sample output:$ afinfo /Users/admin/Desktop/01\ The\ Guns\ of\ August\ 1.m4a Num Tracks: 1 Data format: 2 ch, 44100 Hz, 'alac' (0x00000001) from 16-bit source 4096 frames/packet Channel layout: Stereo (L R) estimated duration: 18702.930431 sec audio bytes: 1006059541 audio packets: 201367 bit rate: 430332 bits per second packet size upper bound: 12334 maximum packet size: 12334 audio data file offset: 48 optimized audio 824799232 valid frames + 0 priming + 0 remainder = 824799232
For any readers unfamiliar with using the terminal, it's quite simple, and you won't break anything. Open Terminal, and type in--or cut and paste from below--the word afinfo followed by a single space:
afinfo
Next, drag an audio file over to the Terminal window and drop it in. You will see the file's path get appended to the afinfo command. If dragging the icon caused the Finder to become the active process, you'll need to click on the Terminal's window to wake it up before the final step of pressing enter to run the command. If you like, you can get information on more than one file at a time by dragging and dropping multiple icons instead of just one. When you're finished, just quit Terminal.app as you would any other program.
I wanted to do this in order to identify which m4a files in a folder were ALAC and which were AAC. This is easily done to an entire folder like this:
afinfo ./*.m4a |grep -B 4 alac
which gives a result like:
File: Track 09.m4a
File type ID: m4af
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, 'alac' (0x00000001) from 16-bit source, 4096 frames/packet
To just get the filenames, I used this:
afinfo ./*.m4a |grep -B 4 alac |grep File: |sed 's/.*\///'
resulting in:
Track 09.m4a
-
A lot of grepping and piping goin' on. Wouldn't
grep -l alac /path/to/file
work for you?– fd0Jan 5, 2019 at 12:38 -
1@fd0: That wouldn't work, but I think this would work better since it would only output the files that were alac:
for file in *.m4a; do if afinfo "$file" | grep -q \'alac\'; then echo "$file"; fi; done
– jjjAug 27, 2019 at 17:27 -
1@jjj - Yes, your solution works. You might add the
-b
option toafinfo
to limit the text output-afinfo -b FILE | ....
– fd0Aug 27, 2019 at 18:09 -
I ended up looking for this type of question
as i needed to to look at the top level of my music hard drive to identify
which ones were alac
so i could convert them to compressed m4a(aac) for better cross platform capabilities.
I wrote a function that looks recursively at the current folder ( i.e. if you need to go deeper than beyond the working directory you ran it on )
if you need to change the depth, the -maxdepth
option can be added to the find
command in $m4a_files
, as well as specifiying paths to not look into, like i have with ! -path "*.app*"
.
I used echo
to print the command to a variable and run it via eval
because I had trouble here and in the past with other command line tools ( like qpdf
) iterating the output of find
into another tool via a for loop.
allu () {
# alac lookup
echo
echo "looking up m4a files"
echo
# bypasses paths with .app in their name so if you run it on some place like ~/Downloads
# and you have an app downloaded there it won't look in it
m4a_files=$( echo $( find . -name "*.m4a" ! -path "*.app*" | sed "s|.*|\"&\"|" ) );
# syntax afinfo $m4a_files |grep -B 4 m4a |grep File: |sed 's/.*\///'
echo 'checking for alac'
echo
# looks alac files up
file_lookup_merger=$( echo "afinfo" $m4a_files "|grep -B 4 alac |grep File: |sed 's/.m4a*\///'" ) ;
# uses eval to return the list of files it found *with srnd. quotes*
eval $file_lookup_merger |sed 's/File: //'| sed "s|.*|\"&\"|";
}
Edit: Come a day later after i wrote the above, I wanted to write a simpler, more cross-compatible verison of this that worked on both mac and linux so I wrote one using Exiftool by Phillip Harvey https://exiftool.org/ ( homebrew install ) https://formulae.brew.sh/formula/exiftool#default
# finds alac files
( find . -name *.m4a -exec exiftool -T -audioformat -filepath {} \; )|grep alac
# prints list of alac files for use as a string separated by spaces
echo $( ( find . -name *.m4a -exec exiftool -T -audioformat -filepath {} \; )|grep alac |sed 's.alac..g'|sed "s|.*|\"&\"|")|sed 's." /."/.g'
If you go to iTunes > View > View Options > Show Columns > Kind
it will include a column that tells you if the file is Apple Lossless or AAC