I want to use codes like this.
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
[query setSearchScopes: [NSArray arrayWithObject: [NSURL fileURLWithPath:@"/Users/Someone/Music" isDirectory:YES]]];
[query setPredicate: predicate];
...
...
Now how do I suppose to set "predicate" to filter out those files with unsupported format??
kMDItemCodezs,kMDItemMediaTypes,kMDItemContentType,kMDItemKind?
Which one should I use? And what are all the possible values of these attibutes corresponding to the supported format in AVAudioPlayer in Lion 10.7? Thanks a lot.
To obtain a list of most supported formats, you can use AudioFileGetGlobalInfo
in the AudioToolbox
framework to get the UTIs supported by Core Audio (using kAudioFileGlobalInfo_AllUTIs
):
UInt32 size;
NSArray *all;
OSStatus err;
err = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_AllUTIs, 0, NULL, &size);
if (err == noErr)
err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AllUTIs, 0, NULL, &size, &all);
if (err == noErr)
NSLog(@"UTIs: %@", all);
[all release];
On 10.7, this gives me:
"public.aiff-audio",
"public.ulaw-audio",
"org.3gpp.adaptive-multi-rate-audio",
"com.microsoft.waveform-audio",
"public.3gpp2",
"com.apple.coreaudio-format",
"public.3gpp",
"public.mp3",
"public.au-audio",
"public.mpeg-4-audio",
"public.mpeg-4",
"com.apple.m4a-audio",
"public.aifc-audio"
Unfortunately UTIs aren't defined for some of the more obscure data formats (e.g. .mp1
/.mp2
) Core Audio supports; if you're happy with the above subset, then just use the UTIs.
Then turn those into a NSMetadataQuery
(kMDItemContentType
for kAudioFileGlobalInfo_AllUTIs
). If you want to cover the rest of the formats, you can match by HFS type and extension: kMDItemFSTypeCode
for kAudioFileGlobalInfo_AllHFSTypeCodes
, and a wildcard match of kMDItemFSName
for kAudioFileGlobalInfo_AllExtensions
. You can use afconvert -hf
to display both of these.
Matching with NSMetadataQuery
will of course not look inside all of the files, so it'll still find text files renamed with a .mp3
extension. Since Spotlight does try to index other audio attributes, you could try checking kMDItemAudioBitRate
and so forth; these will be missing on a file that isn't actually an audio file. Depending on how accurate you want to be in filtering, you can also try opening each file to see if it's playable.
Use kMDItemContentTypeTree
, and the audio type. This will match any audio files, ignoring movie files. If you want to include movie files, search for the audio-visual content type, which the audio type conforms to (descends from).
Edit: This will match all known audio types, regardless of whether Core Audio (let alone AVAudioPlayer) can play them. Nicholas Riley's solution is better.