美文网首页
AV Foundation ⑦ 元数据(AVMetadataIt

AV Foundation ⑦ 元数据(AVMetadataIt

作者: _涼城 | 来源:发表于2022-06-03 09:46 被阅读0次

媒体元数据

    媒体容器格式会存储有关其媒体的描述性元数据。对于开发人员来说,使用元数据具有一定的挑战性,因为每种容器格式都有自己独特的元数据格式,需要对相应格式读写操作的底层技术有所了解。不过 AV Foundation 让这一切变得简单,它提供了 AVMetadataItem 类用于统一处理媒体元数据,使得开发者不需要考虑大多数特定格式的细节。

元数据格式

加载资产的元数据

    AVAssetAVAssetTrack 提供了三种方法可以获取相关的元数据,要了解这三种方法的适用范围,首先要了解 keySpace 的含义。AV Foundation 使用 AVMetadataKeySpace 将各个键组合在一起的方法,可以实现对 AVMetadataItem 实例集合的筛选。

avassetAndTracks_2x.png

CommonMetadata

    每个资源至少有一个 AVMetadataKeySpaceCommon 通用键空间供从中获取元数据。AVMetadataKeySpaceCommon 用来定义所有支持的媒体类型的键,包括诸如名称,作者,描述等常见元素,这提供了一种对所有支持的媒体格式进行一定级别的元数据标准化的过程。开发者可以通过查询 AVAsset 或者 AVAssetTrackcommonMetadata 属性获取元数据。

NSArray *keys = @[@"commonMetadata"];
[anAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
    NSLog(@"CommonMetadata:%ld\n",anAsset.commonMetadata.count);
    for (AVMetadataItem *item in anAsset.commonMetadata) {
        NSLog(@"CommonMetadata,%@:%@\n",item.key,item.value);
    }
}];

metadataForFormat

    访问指定格式的元数据需要在 AVAsset 或者 AVAssetTrack 上调用 metadataForFormat方法。这个方法包含一个用于定义数据格式的 NSString 对象返回一个包含所有相关元数据信息的 NSArrayAVMetadataFormat.h 文件为不同的元数据格式提供对应的字符串常量。与硬编码某个具体的元数据格式字符串不同,可以通过 availableMetadataFormats 获取包含的所有元数据格式。

NSArray *keys = @[@"availableMetadataFormats"];
[anAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
    AVKeyValueStatus status = [anAsset statusOfValueForKey:@"availableMetadataFormats" error:&error];
    if(statuc == AVKeyValueStatusLoaded){
      NSMutableArray *availableMetadatas = [NSMutableArray array];
      for (NSString *format in anAsset.availableMetadataFormats) {
          [availableMetadatas addObjectsFromArray:[anAsset metadataForFormat:format]];

      }
      NSLog(@"availablemetadatas.count:%ld\n",availableMetadatas.count);
      for (AVMetadataItem *item in availableMetadatas) {
          NSLog(@"availablemetadatas,%@:%@:%@\n",item.keySpace,item.key,item.value);
      }
    }
}];

注意: 调用 metadataForFormat: 时要确保 availableMetadataFormats 已经加载

metadata

    AV Foundation 在 iOS 8.0 提供了 metadata 方法查询 AVAsset 所有可用的元数据数组。

 NSArray *keys = @[@"metadata"];
 [anAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
    NSError *error;
    AVKeyValueStatus status = [anAsset statusOfValueForKey:@"metadata" error:&error];
    if(status == AVKeyValueStatusLoaded){
        NSLog(@"metadata:%ld\n",anAsset.metadata.count);
        for (AVMetadataItem *item in anAsset.metadata) {
            NSLog(@"metadatas,%@:%@\n",item.key,item.value);
        }
    }
}];

查找元数据

    当我们得到一个包含元数据项的数组时,通常希望找到所需的具体元数据值。一个特别有效的方法是使用 AVMetadataItem 提供的便利方法,获取结果集合并对其进行筛选。 AVMetadataItem 在早期通过metadataItemsFromArray:metadatawithKey:keySpace: 过滤指定的元数据,例如,如果开发者希望获得一个 .MOV 视频文件的标题,需要按如下方法获取:

NSArray *metadata = <#AVMetadataItem 的集合#>;
NSString * keySpace = AVMetadataKeySpaceCommon;
NSString *titleKey = AVMetadataCommonKeyTitle;
NSArray *titleMetadata = [AVMetadataItem metadataItemsFromArray:metadatawithKey:AVMetadataCommonKeyTitle keySpace:AVMetadataKeySpaceCommon];

    后来,上述方法已经不建议使用。提供了新的方法用于查找指定的元数据:

  • metadataItemsFromArray:filteredAndSortedAccordingToPreferredLanguages:
  • metadataItemsFromArray:filteredByIdentifier:
  • metadataItemsFromArray:filteredByMetadataItemFilter:

    例如,查找特定元数据项的最简单方法是按 AVMetadataIdentifier(标识符)过滤,它将键空间和键组合成一个单元。以下示例显示了如何从公共键空间中检索标题项:

NSArray *metadata = <#AVMetadataItem 的集合#>;
NSArray *metadatas = [AVMetadataItem metadataItemsFromArray:availableMetadatas filteredByIdentifier:AVMetadataCommonIdentifierTitle];

使用元数据

    AVMetadataItem 最基本的形式其实是一个封装键值对的容器。可通过它定义的 AVMetadataKey commonKey,查询其是否存在于公共键空间内,而 keyvalue 都被定义成 id <NSObject, NSCopying> 形式,它可能是 NSStringNSNumber等情况。如果开发者已经提前知道 value 的类型,AVMetadataItem 提供三个类型强制属性stringValuenumberValuedataValue

    由于 AVMetadataItemkey 是泛类型,我们在使用时可能存在获取错误的情况,因此可以在 AVMetadataItem 上添加一个名为 keyString 的分类方法从而获取 key 的字符串:

- (NSString *)keyString {
    if ([self.key isKindOfClass:[NSString class]]) {                        // 1
        return (NSString *)self.key;
    }
    else if ([self.key isKindOfClass:[NSNumber class]]) {

        UInt32 keyValue = [(NSNumber *) self.key unsignedIntValue];         // 2
        
        // Most, but not all, keys are 4 characters ID3v2.2 keys are
        // only be 3 characters long.  Adjust the length if necessary.
        
        size_t length = sizeof(UInt32);                                     // 3
        if ((keyValue >> 24) == 0) --length;
        if ((keyValue >> 16) == 0) --length;
        if ((keyValue >> 8) == 0) --length;
        if ((keyValue >> 0) == 0) --length;
        
        long address = (unsigned long)&keyValue;
        address += (sizeof(UInt32) - length);

        // keys are stored in big-endian format, swap
        keyValue = CFSwapInt32BigToHost(keyValue);                          // 4

        char cstring[length];                                               // 5
        strncpy(cstring, (char *) address, length);
        cstring[length] = '\0';

        // Replace '©' with '@' to match constants in AVMetadataFormat.h
        if (cstring[0] == '\xA9') {                                         // 6
            cstring[0] = '@';
        }

        return [NSString stringWithCString:(char *) cstring                 // 7
                                  encoding:NSUTF8StringEncoding];

    }
    else {
        return @"<<unknown>>";
    }
}

相关文章

网友评论

      本文标题:AV Foundation ⑦ 元数据(AVMetadataIt

      本文链接:https://www.haomeiwen.com/subject/jvncmrtx.html