如何检查 AVMetadataItem 项(如 Title、Artist 等)是否为空或不存在?
How can I check if AVMetadataItem items like Title, Artist, etc , are null or don't exist?
我正在构建一个音乐应用程序,我正在尝试使用这段代码获取 MP3 文件元数据:
for (NSString *format in [assest availableMetadataFormats]) {
for (AVMetadataItem *item in [assest metadataForFormat:format]) {
if ([[item commonKey] isEqualToString:@"title"]) {
[SongNameMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}
if ([[item commonKey] isEqualToString:@"artist"]) {
[ArtistMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}
if ([[item commonKey] isEqualToString:@"albumName"]) {
}
if ([[item commonKey] isEqualToString:@"artwork"]) {
UIImage *img = nil;
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
img = [UIImage imageWithData:item.dataValue];
}
else {
NSDictionary *dict ;
[item.value copyWithZone:nil];
img = [UIImage imageWithData:[dict objectForKey:@"data"]];
}
}
}
}
代码运行良好。唯一的问题是,当可变数组被填充时,它们会按照以下方式进行:
- SongNameMutableArray => [歌曲 1、歌曲 2、歌曲 3、歌曲 X];
- ArtistMutableArray => [艺术家 1、艺术家 3、艺术家 10、艺术家 X];
因为并非所有歌曲的元数据中都有艺术家。
根据代码的这个特定部分
if ([[item commonKey] isEqualToString:@"artist"]) {
[ArtistMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}
如果找到的项目是艺术家,则将其插入数组。
现在我的问题是如何检测歌曲的元数据中何时没有艺术家?这样我就可以在 ArtistMutableArray 中插入 "null" => [Artists1, null, Artist3, null, Artist 5, ArtistX];
我试过:
if ([[item commonKey] isEqualToString:@"null"])
if ([[item value] isEqualToString:@"null"])
我不确定我在这里遗漏了什么。
你所做的一切都需要以不同的方式来完成。不要将数据拆分到单独的数组中,特别是如果您希望每个数组具有相同数量的元素并且每个对应的索引引用相同的资产。
相反,定义一个 class,其中包含您要为每个资产跟踪的几个属性。然后拥有这些 class 个实例的单个数组。然后就无需担心保持多个数组同步并通过在需要的地方向数组添加 "null" 值来执行技巧。
拥有一组数据还有很多其他好处。例如排序。例如,通过拥有一个数组,您可以按艺术家对一组数据进行排序。在排序或过滤时试图保持多个数组同步是一个巨大的痛苦。
由于您只获得通用元数据,因此无需遍历所有格式并查看每种格式的属性。只需使用资产的 commonMetadata
属性。
获取 commonKey
值时,不要将其与硬编码字符串进行比较。使用 API 提供的常量,例如 AVMetadataCommonKeyAlbumName
.
并且由于每个元数据项只能有一个 commonKey
值,因此使用 if/else
可以使您的代码更高效。并使用元数据项的 stringValue
属性 来获取字符串值,而不是使用 stringWithFormat
.
这是元数据的开始 class。根据您的喜好命名并添加您需要的任何其他属性。
@interface MyMetaData: NSObject
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *artist;
@property (nonatomic, copy) NSString *albumName;
@property (nonatomic, copy) UIImage *artwork;
@end
@implementation MyMetaData
@end
这里是您在问题中发布的代码的替换:
NSMutableArray *metadata = [NSMutableArray array]; // your array of obtained metadata
AVAsset *asset = // some asset
MyMetaData *data = [[MyMetaData alloc] init];
NSArray *commonData = asset.commonMetadata;
for (AVMetadataItem *item in commonData) {
AVMetadataKey key = item.commonKey;
if ([key isEqual: AVMetadataCommonKeyTitle]) {
data.title = item.stringValue;
} else if ([key isEqual:AVMetadataCommonKeyArtist]) {
data.artist = item.stringValue;
} else if ([key isEqual:AVMetadataCommonKeyAlbumName]) {
data.albumName = item.stringValue;
} else if ([key isEqual:AVMetadataCommonKeyArtwork]) {
data.artwork = // your code to get the image
}
}
[metadata addObject:data];
这样更简洁,您现在只需处理一个数组。如果给定的资产没有数据,例如艺术家,那么该值将在给定的 MyMetaData
实例上保持 nil
。
我正在构建一个音乐应用程序,我正在尝试使用这段代码获取 MP3 文件元数据:
for (NSString *format in [assest availableMetadataFormats]) {
for (AVMetadataItem *item in [assest metadataForFormat:format]) {
if ([[item commonKey] isEqualToString:@"title"]) {
[SongNameMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}
if ([[item commonKey] isEqualToString:@"artist"]) {
[ArtistMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}
if ([[item commonKey] isEqualToString:@"albumName"]) {
}
if ([[item commonKey] isEqualToString:@"artwork"]) {
UIImage *img = nil;
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
img = [UIImage imageWithData:item.dataValue];
}
else {
NSDictionary *dict ;
[item.value copyWithZone:nil];
img = [UIImage imageWithData:[dict objectForKey:@"data"]];
}
}
}
}
代码运行良好。唯一的问题是,当可变数组被填充时,它们会按照以下方式进行:
- SongNameMutableArray => [歌曲 1、歌曲 2、歌曲 3、歌曲 X];
- ArtistMutableArray => [艺术家 1、艺术家 3、艺术家 10、艺术家 X];
因为并非所有歌曲的元数据中都有艺术家。
根据代码的这个特定部分
if ([[item commonKey] isEqualToString:@"artist"]) {
[ArtistMutableArray addObject:[NSString stringWithFormat:@"%@",[item value]]];
}
如果找到的项目是艺术家,则将其插入数组。
现在我的问题是如何检测歌曲的元数据中何时没有艺术家?这样我就可以在 ArtistMutableArray 中插入 "null" => [Artists1, null, Artist3, null, Artist 5, ArtistX];
我试过:
if ([[item commonKey] isEqualToString:@"null"])
if ([[item value] isEqualToString:@"null"])
我不确定我在这里遗漏了什么。
你所做的一切都需要以不同的方式来完成。不要将数据拆分到单独的数组中,特别是如果您希望每个数组具有相同数量的元素并且每个对应的索引引用相同的资产。
相反,定义一个 class,其中包含您要为每个资产跟踪的几个属性。然后拥有这些 class 个实例的单个数组。然后就无需担心保持多个数组同步并通过在需要的地方向数组添加 "null" 值来执行技巧。
拥有一组数据还有很多其他好处。例如排序。例如,通过拥有一个数组,您可以按艺术家对一组数据进行排序。在排序或过滤时试图保持多个数组同步是一个巨大的痛苦。
由于您只获得通用元数据,因此无需遍历所有格式并查看每种格式的属性。只需使用资产的 commonMetadata
属性。
获取 commonKey
值时,不要将其与硬编码字符串进行比较。使用 API 提供的常量,例如 AVMetadataCommonKeyAlbumName
.
并且由于每个元数据项只能有一个 commonKey
值,因此使用 if/else
可以使您的代码更高效。并使用元数据项的 stringValue
属性 来获取字符串值,而不是使用 stringWithFormat
.
这是元数据的开始 class。根据您的喜好命名并添加您需要的任何其他属性。
@interface MyMetaData: NSObject
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *artist;
@property (nonatomic, copy) NSString *albumName;
@property (nonatomic, copy) UIImage *artwork;
@end
@implementation MyMetaData
@end
这里是您在问题中发布的代码的替换:
NSMutableArray *metadata = [NSMutableArray array]; // your array of obtained metadata
AVAsset *asset = // some asset
MyMetaData *data = [[MyMetaData alloc] init];
NSArray *commonData = asset.commonMetadata;
for (AVMetadataItem *item in commonData) {
AVMetadataKey key = item.commonKey;
if ([key isEqual: AVMetadataCommonKeyTitle]) {
data.title = item.stringValue;
} else if ([key isEqual:AVMetadataCommonKeyArtist]) {
data.artist = item.stringValue;
} else if ([key isEqual:AVMetadataCommonKeyAlbumName]) {
data.albumName = item.stringValue;
} else if ([key isEqual:AVMetadataCommonKeyArtwork]) {
data.artwork = // your code to get the image
}
}
[metadata addObject:data];
这样更简洁,您现在只需处理一个数组。如果给定的资产没有数据,例如艺术家,那么该值将在给定的 MyMetaData
实例上保持 nil
。