Vignesh
Vignesh

Reputation: 10251

Extracting MP3 Album artwork in iOS

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];

Upvotes: 2

Views: 5883

Answers (2)

Sishu
Sishu

Reputation: 1558

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;
    }
}

Upvotes: 0

Amir Kh.
Amir Kh.

Reputation: 444

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]];
        }
    }
}];

Upvotes: 6

Related Questions