在iOS中提取MP3专辑封面艺术品

3
我一直在尝试从一个.mp3文件中提取元数据信息,以供iPhone应用程序使用。我尝试使用AVAsset,就像this。但它没起作用,常见的元数据是空的。但是audacity和另一个来自应用商店的iOS应用程序可以检索元数据详细信息。我不知道为什么?
因此,我尝试使用AudioToolBox框架下面的代码来提取相同的内容。
    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];

这段代码返回了除专辑封面以外的所有内容。当我尝试使用kAudioFilePropertyAlbumArtwork提取专辑封面时,我遇到了osstatus错误(无法完成操作)。因此,最后我尝试了ObjC包装器libId3(在这里找到)。它完美地解决了我的问题,我可以得到专辑封面。
我的问题是,为什么AVAsset不能检索数据?我错过了什么吗?有人设法使它工作了吗?如果有示例,将不胜感激。
为什么无法提取kAudioFilePropertyAlbumArtwork?这两个问题都发生在我拥有的所有.mp3文件中。
解决方案更新:由于我使用的URL是用以下方式创建的,所以AVAsset对我不起作用。
 [NSURL URLWithString:[filePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]

而不是
    NSURL *fileURL = [NSURL fileURLWithPath:filePath];
2个回答

7

使用AVAsset提取元数据信息,这篇帖子很有用。以下代码是您需要的:

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

我已经检查了这篇文章。我的问题是“commonMetadata”返回一个空数组。我的意思是没有“keys”。但是信息确实存在,我可以用audiotoolbox提取相同的信息。这在我所有的mp3文件中都发生。 - Vignesh
我使用了这段代码,它完美地提取了专辑封面。你能否提供你所用的mp3文件或者你的代码链接? - Amir Kh.
我可以提供我使用的mp3文件链接。我尝试了你上面粘贴的相同代码。这个链接(http://starmusiq.com/Composer.asp?Composer=A.R.Rahman&RecNextPg=4)有一些mp3文件,你可以随便试试。 - Vignesh
请注意,我已经下载了文件。我没有在流媒体上播放。你能提供你的 .mp3 文件链接吗?我可以试一下。 - Vignesh
我从那个网站下载了一个 .mp3 文件并测试了一下... 一切都运行良好。这是代码:http://www.4shared.com/zip/SW9p8k85/removeMe.html - Amir Kh.
显示剩余3条评论

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接