3

I have been trying to extract metadata information from a .mp3 file for an iPhone app. I tried using AVAsset like this.It didn't work,the common meta data is empty. But audacity and another iOS app from app store could retrieve the meta data details. I don't know why?.

So, I tried to extract the same with below code using AudioToolBox framework

    CFDictionaryRef piDict = nil;
    UInt32 piDataSize = sizeof(piDict);

    //  Populates a CFDictionary with the ID3 tag properties
    err = AudioFileGetProperty(fileID, kAudioFilePropertyInfoDictionary, &piDataSize, &piDict);
    if(err != noErr) {
        NSLog(@"AudioFileGetProperty failed for property info dictionary");
        return nil;
    }

    //  Toll free bridge the CFDictionary so that we can interact with it via objc
    NSMutableDictionary* nsDict = [(__bridge NSDictionary*)piDict mutableCopy];

This returned everything except album art. When I tried to extract the album art using kAudioFilePropertyAlbumArtwork , I got osstatus error(The operation couldn't be completed).

So at last, I tried my luck with ObjC wrapper for libId3(found here). It worked perfectly well. I could get the artwork.

My question is, why AVAsset could not retrieve the data?. What am I missing there?. somebody managed to to get it work?. A sample will be appreciated.

Why kAudioFilePropertyAlbumArtwork extraction couldn't be completed?. Both the issues happened with all the .mp3 files I had.

Solution Update:

AVAsset didn't work for me because I made my URL using

 [NSURL URLWithString:[filePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]

rather than

    NSURL *fileURL = [NSURL fileURLWithPath:filePath];
Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
Vignesh
  • 10,205
  • 2
  • 35
  • 73

2 Answers2

7

To use AVAsset to extract metadata informations, this post is useful. The following code is what you need:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"mp3"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
AVAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];

NSArray *keys = [NSArray arrayWithObjects:@"commonMetadata", nil];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
    NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata
                                                       withKey:AVMetadataCommonKeyArtwork
                                                      keySpace:AVMetadataKeySpaceCommon];

    for (AVMetadataItem *item in artworks) {
        if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) {
            NSDictionary *dict = [item.value copyWithZone:nil];
            self.imageView.image = [UIImage imageWithData:[dict objectForKey:@"data"]];
        } else if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
            self.imageView.image = [UIImage imageWithData:[item.value copyWithZone:nil]];
        }
    }
}];
Community
  • 1
  • 1
Amir Kh.
  • 446
  • 4
  • 11
  • I checked the post already. My problem is "commonMetadata" return empty array. I mean no "keys". But information is there and I could extract the same with audiotoolbox. It happens with all the mp3 file I have. – Vignesh May 02 '13 at 07:29
  • I used this code and it extract the albumArt perfectly. Can you link a mp3 file you used or maybe your code? – Amir Kh. May 02 '13 at 08:06
  • I can link the mp3 file I used. I tried the same code you have pasted above.The link(http://starmusiq.com/Composer.asp?Composer=A.R.Rahman&RecNextPg=4) has few mp3 files, you can try with anything. – Vignesh May 02 '13 at 08:47
  • FYI, I have file downloaded.I was not streaming.can you link your .mp3 file I can try that. – Vignesh May 02 '13 at 08:54
  • I downloaded a .mp3 file from that site and test it... Everything works well. Here is the code: http://www.4shared.com/zip/SW9p8k85/removeMe.html – Amir Kh. May 02 '13 at 12:41
  • +1 for your time. It does work. But I am not sure y it didn't work for me. I think its got to do with something in my app. Thank you. – Vignesh May 03 '13 at 09:19
  • What if I have a image url or server path of image ? – Waqas Nov 11 '16 at 10:52
  • I have an mp3 in the `AVMetadataKeySpaceID3` `keySpace`, but I'm finding that `item.value` *is* the image data, not a dictionary wrapper around the image data -- can anyone provide a link to a source on how to definitively extract this data? – Jeff V Sep 06 '17 at 22:55
1
NSURL *fileURL1 = [NSURL fileURLWithPath:url];
AVAsset *asset = [AVAsset assetWithURL:fileURL1];


for (AVMetadataItem *metadataItem in asset.commonMetadata) {
    if ([metadataItem.commonKey isEqualToString:@"artwork"]){
        NSDictionary *imageDataDictionary = (NSDictionary *)metadataItem.value;
        NSData *imageData = [imageDataDictionary objectForKey:@"data"];
        UIImage *image = [UIImage imageWithData:imageData];
        imageThumb.image = image;
    }
}
Sishu
  • 1,510
  • 1
  • 21
  • 48