Sta*_*mes 9 mp3 objective-c avfoundation ipad ios-simulator
编辑:罪魁祸首是iOS 8,而不是模拟器(我没有意识到已经运行iOS 8)我已经重命名标题以反映这一点.
我很高兴使用这个SO问题的代码从mp3文件加载专辑封面.这是在我的带有iOS 7.1的iPhone 5上.
但后来我在iOS模拟器中跟踪崩溃到这段代码.进一步的调查显示,这个代码也在我的iPad上崩溃了.升级到iOS 8后,它在我的iPad上崩溃了.
看来包含图像的字典已损坏.
我创建了一个虚拟iOS项目,只加载专辑封面并得到相同的结果.下面是该viewcontroller的代码.
- (void) viewDidAppear:(BOOL)animated
{
self.titleText = @"Overkill"; // Set song filename here
NSString *filePath = [[NSBundle mainBundle] pathForResource:self.titleText ofType:@"mp3"];
if (!filePath) {
return;
}
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSLog(@"Getting song metadata for %@", self.titleText);
AVAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
if (asset != nil) {
NSArray *keys = [NSArray arrayWithObjects:@"commonMetadata", nil];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata
withKey:AVMetadataCommonKeyArtwork
keySpace:AVMetadataKeySpaceCommon];
UIImage *albumArtWork;
for (AVMetadataItem *item in artworks) {
if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) {
NSDictionary *dict = [item.value copyWithZone:nil];
// **********
// Crashes here with SIGABRT. dict is not a valid dictionary.
// **********
if ([dict objectForKey:@"data"]) {
albumArtWork = [UIImage imageWithData:[dict objectForKey:@"data"]];
}
}
else if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
// This doesn't appear to get called for images set (ironically) in iTunes
albumArtWork = [UIImage imageWithData:[item.value copyWithZone:nil]];
}
}
if (albumArtWork != nil) {
dispatch_sync(dispatch_get_main_queue(), ^{
[self.albumArtImageView setImage:albumArtWork];
});
}
}];
}
}
Run Code Online (Sandbox Code Playgroud)
我已经标记了崩溃线.它希望文件Overkill.mp3在捆绑中.我测试了多个mp3和m4a从iTunes和亚马逊导出,所以我知道文件本身是正确编码的.
在Xcode 6.0和6.1中测试过.
任何想法为什么它可以在iPhone上工作但不适用于模拟器或iPad?
编辑/更新:
记录item.value会显示差异.
在iPhone 5上(正常):
(lldb) po item.value
{
MIME = JPG;
data = <ffd8ffe0 .... several Kb of data ..... 2a17ffd9>;
identifier = "";
picturetype = Other;
}
Run Code Online (Sandbox Code Playgroud)
在模拟器上(崩溃)
(lldb) po item.value
<ffd8ffe0 .... several Kb of data ..... 2a17ffd9>
Run Code Online (Sandbox Code Playgroud)
因此,似乎在模拟器上没有字典,只有原始图稿.
更改代码不要期望字典,但item.value作为UIImage 工作!
for (AVMetadataItem *item in artworks) {
if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) {
NSData *newImage = [item.value copyWithZone:nil];
albumArtWork = [UIImage imageWithData:newImage];
}
...
}
Run Code Online (Sandbox Code Playgroud)
Sta*_*mes 17
看来返回的数据结构中的iOS 8.改变value的AVMetadataItem对象不再是一本字典,但实际的原始UIImage数据.
添加测试可以NSFoundationVersionNumber解决问题.可能有一个更清洁的解决方案.
- (void) viewDidAppear:(BOOL)animated
{
self.titleText = @"Overkill";
NSString *filePath = [[NSBundle mainBundle] pathForResource:self.titleText ofType:@"mp3"];
if (!filePath) {
return;
}
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSLog(@"Getting song metadata for %@", self.titleText);
AVAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
if (asset != nil) {
NSArray *keys = [NSArray arrayWithObjects:@"commonMetadata", nil];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
NSArray *artworks = [AVMetadataItem metadataItemsFromArray:asset.commonMetadata
withKey:AVMetadataCommonKeyArtwork
keySpace:AVMetadataKeySpaceCommon];
UIImage *albumArtWork;
for (AVMetadataItem *item in artworks) {
if ([item.keySpace isEqualToString:AVMetadataKeySpaceID3]) {
// *** WE TEST THE IOS VERSION HERE ***
if (TARGET_OS_IPHONE && NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
NSData *newImage = [item.value copyWithZone:nil];
albumArtWork = [UIImage imageWithData:newImage];
}
else {
NSDictionary *dict = [item.value copyWithZone:nil];
if ([dict objectForKey:@"data"]) {
albumArtWork = [UIImage imageWithData:[dict objectForKey:@"data"]];
}
}
}
else if ([item.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
// This doesn't appear to get called for images set (ironically) in iTunes
albumArtWork = [UIImage imageWithData:[item.value copyWithZone:nil]];
}
}
if (albumArtWork != nil) {
dispatch_sync(dispatch_get_main_queue(), ^{
[self.albumArtImageView setImage:albumArtWork];
});
}
}];
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1429 次 |
| 最近记录: |