Search code examples
cocoametadataspotlight

How can I find out all audio files whose formats are supported by AVAudioPlayer in Lion 10.7?


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.


Solution

  • 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.