AVMetadataItem其實(shí)就是一個(gè)模型類(lèi), 主要是用來(lái)保存音視頻等多媒體資料的各種附加信息。稱(chēng)之為元數(shù)據(jù)壤躲。
例如:作者, 標(biāo)題备燃, 創(chuàng)建時(shí)間柒爵, 封面等描述關(guān)于這個(gè)多媒體的一些常見(jiàn)描述信息。
在分析這個(gè)之前赚爵,大家可以下載一個(gè)元數(shù)據(jù)分析工具棉胀,對(duì)一個(gè)多媒體文件進(jìn)行詳細(xì)的分析法瑟, 有助于我們學(xué)習(xí)AVFoundation, 大家可以去蘋(píng)果工具下載中心 搜索Atom Inspector 進(jìn)行下載
大家也可以到AVFoundation(二):核心AVAsset先去了解一下AVFoundation核心類(lèi),詳細(xì)介紹了Atom Inspector的用法 這里主要介紹AVMetadataItem
- AVMetadataItem獲取
AVMetadataItem還有一個(gè)子類(lèi)AVMutableMetadataItem唁奢, 他們兩主要的區(qū)別就是一個(gè)不可變霎挟, 一個(gè)可變的, AVMetadataItem的屬性基本都是只讀(readonly)的麻掸, 而AVMutableMetadataItem的屬性是可讀可寫(xiě)(readwrite)酥夭。
AVMutableMetadataItem 除了常規(guī)的init的方法創(chuàng)建還可以通過(guò)+ (AVMutableMetadataItem *)metadataItem; 這個(gè)類(lèi)方法創(chuàng)建。
AVMetadataItem: 這個(gè)一般不自己創(chuàng)建而是從AVAssetTrack 和 AVAsset獲取到AVMetadataItem數(shù)組脊奋, 一個(gè)AVMetadataItem對(duì)象存放著一個(gè)信息熬北。
NSURL *assetUrl = [[NSBundle mainBundle] URLForResource:@"Hubblecast" withExtension:@"mov"];
AVAsset *videoAsset = [AVAsset assetWithURL:assetUrl];
NSArray *keys = @[@"tracks", @"availableMetadataFormats"];
[self obtainAVMetadataItem:videoAsset];
[videoAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
NSError *error = nil;
//獲取加載tracks的狀態(tài), 作出相應(yīng)的操作
AVKeyValueStatus status = [videoAsset statusOfValueForKey:@"tracks" error:&error];
switch (status) {
case AVKeyValueStatusUnknown:
NSLog(@"AVKeyValueStatusUnknown");
//加載tracks未知錯(cuò)誤
break;
case AVKeyValueStatusFailed:
NSLog(@"AVKeyValueStatusFailed");
//加載tracks失敗
break;
case AVKeyValueStatusLoading:
NSLog(@"AVKeyValueStatusLoading");
//加載tracks中
break;
case AVKeyValueStatusLoaded:
NSLog(@"AVKeyValueStatusLoaded");
//加載tracks完畢
break;
case AVKeyValueStatusCancelled:
NSLog(@"AVKeyValueStatusCancelled");
//取消加載tracks
break;
}
status = [videoAsset statusOfValueForKey:@"availableMetadataFormats" error:&error];
switch (status) {
case AVKeyValueStatusUnknown:
NSLog(@"AVKeyValueStatusUnknown");
//加載AVKeyValueStatusUnknown未知錯(cuò)誤
break;
case AVKeyValueStatusFailed:
NSLog(@"AVKeyValueStatusFailed");
//加載AVKeyValueStatusUnknown失敗
break;
case AVKeyValueStatusLoading:
NSLog(@"AVKeyValueStatusLoading");
//加載AVKeyValueStatusUnknown中
break;
case AVKeyValueStatusLoaded:
{
NSLog(@"AVKeyValueStatusLoaded");
//加載AVKeyValueStatusUnknown完畢
//獲取videoAsset里面的元數(shù)據(jù)
NSMutableArray *metadata = [NSMutableArray array];
for (NSString *format in videoAsset.availableMetadataFormats) {
NSLog(@"%@", format);
NSLog(@"%@", [videoAsset metadataForFormat:format]);
[metadata addObject:[videoAsset metadataForFormat:format]];
}
for (AVMetadataItem *item in metadata.firstObject) {
NSLog(@"%@--%@\n",item.key, item.value);
}
[self keySpac:metadata];
break;
}
case AVKeyValueStatusCancelled:
NSLog(@"AVKeyValueStatusCancelled");
//取消加載AVKeyValueStatusUnknown
break;
}
}];
這里要注意的是AVFoundation里面很多類(lèi)的屬性都是用到時(shí)才加載诚隙,對(duì)于一些加載過(guò)程中比較耗時(shí)的屬性讶隐,遵守了AVAsynchronousKeyValueLoading
這個(gè)協(xié)議,使用異步加載的方式久又,防止界面卡頓
loadValuesAsynchronouslyForKeys 和 statusOfValueForKey
使用注意點(diǎn)
loadValuesAsynchronouslyForKeys 中的不管在keys中設(shè)置了多少個(gè)屬性值巫延, completionHandler只會(huì)調(diào)用一次,
所以在 completionHandler中獲取 AVKeyValueStatus狀態(tài)在keys有多個(gè)是不準(zhǔn)確的地消, 得每個(gè)屬性分開(kāi)炉峰, 一個(gè)key對(duì)應(yīng)一個(gè)statusOfValueForKey中獲取加載狀態(tài)
- AVMetadataItem分析
我們打印這個(gè)視頻的創(chuàng)建時(shí)間AVMetadataItem出來(lái)看看:
"<AVMetadataItem: 0x6100000139f0, identifier=mdta/com.apple.quicktime.year, keySpace=mdta, key class = __NSCFString, key=com.apple.quicktime.year, commonKey=(null), extendedLanguageTag=en-US, dataType=com.apple.metadata.datatype.UTF-8, time={INVALID}, duration={INVALID}, startDate=(null), extras={\n dataType = 1;\n dataTypeNamespace = \"com.apple.quicktime.mdta\";\n}, value=2013>"
再結(jié)合他的屬性:
/* Indicates the identifier of the metadata item. Publicly defined identifiers are declared in AVMetadataIdentifiers.h. */
@property (nonatomic, readonly, copy, nullable) NSString *identifier NS_AVAILABLE(10_10, 8_0);
/* indicates the IETF BCP 47 (RFC 4646) language identifier of the metadata item; may be nil if no language tag information is available */
@property (nonatomic, readonly, copy, nullable) NSString *extendedLanguageTag NS_AVAILABLE(10_10, 8_0);
/* indicates the locale of the metadata item; may be nil if no locale information is available for the metadata item */
@property (nonatomic, readonly, copy, nullable) NSLocale *locale;
/* indicates the timestamp of the metadata item. */
@property (nonatomic, readonly) CMTime time;
/* indicates the duration of the metadata item */
@property (nonatomic, readonly) CMTime duration NS_AVAILABLE(10_7, 4_2);
/* indicates the data type of the metadata item's value. Publicly defined data types are declared in <CoreMedia/CMMetadata.h> */
@property (nonatomic, readonly, copy, nullable) NSString *dataType NS_AVAILABLE(10_10, 8_0);
/* provides the value of the metadata item */
@property (nonatomic, readonly, copy, nullable) id<NSObject, NSCopying> value;
/* provides a dictionary of the additional attributes */
@property (nonatomic, readonly, copy, nullable) NSDictionary<NSString *, id> *extraAttributes;
可以看出, 每個(gè)屬性相對(duì)應(yīng)的值脉执。所以我們可以很直觀的把AVMetadataItem就是我們平時(shí)開(kāi)發(fā)中用到的模型疼阔。里面都是鍵值對(duì)的存在 。
- 篩選AVMetadataItem
/*!
@method metadataItemsFromArray:withLocale:
@discussion Instead, use metadataItemsFromArray:filteredAndSortedAccordingToPreferredLanguages:.
*/
+ (NSArray<AVMetadataItem *> *)metadataItemsFromArray:(NSArray<AVMetadataItem *> *)metadataItems withLocale:(NSLocale *)locale;
/*!
@method metadataItemsFromArray:withKey:keySpace:
@discussion Instead, use metadataItemsFromArray:filteredByIdentifier:.
*/
+ (NSArray<AVMetadataItem *> *)metadataItemsFromArray:(NSArray<AVMetadataItem *> *)metadataItems withKey:(nullable id)key keySpace:(nullable NSString *)keySpace;
/*!
@method metadataItemsFromArray:filteredAndSortedAccordingToPreferredLanguages:
@abstract Filters an array of AVMetadataItems according to whether their locales match any language identifier in the specified array of preferred languages. The returned array is sorted according to the order of preference of the language each matches.
@param metadataItems
An array of AVMetadataItems to be filtered and sorted.
@param preferredLanguages
An array of language identifiers in order of preference, each of which is an IETF BCP 47 (RFC 4646) language identifier. Use +[NSLocale preferredLanguages] to obtain the user's list of preferred languages.
@result An instance of NSArray containing metadata items of the specified NSArray that match a preferred language, sorted according to the order of preference of the language each matches.
*/
+ (NSArray<AVMetadataItem *> *)metadataItemsFromArray:(NSArray<AVMetadataItem *> *)metadataItems filteredAndSortedAccordingToPreferredLanguages:(NSArray<NSString *> *)preferredLanguages NS_AVAILABLE(10_8, 6_0);
/*!
@method metadataItemsFromArray:filteredByIdentifier:
@abstract Filters an array of AVMetadataItems according to identifier.
@param metadataItems
An array of AVMetadataItems to be filtered by identifier.
@param identifier
The identifier that must be matched for a metadata item to be copied to the output array. Items are considered a match not only when their identifiers are equal to the specified identifier, and also when their identifiers conform to the specified identifier.
@result An instance of NSArray containing the metadata items of the target NSArray that match the specified identifier.
*/
+ (NSArray<AVMetadataItem *> *)metadataItemsFromArray:(NSArray<AVMetadataItem *> *)metadataItems filteredByIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
/*!
@method metadataItemsFromArray:filteredByMetadataItemFilter:
@abstract Filters an array of AVMetadataItems using the supplied AVMetadataItemFilter.
@param metadataItems
An array of AVMetadataItems to be filtered.
@param metadataItemFilter
The AVMetadataItemFilter object for filtering the metadataItems.
@result An instance of NSArray containing the metadata items of the target NSArray that have not been removed by metadataItemFilter.
*/
+ (NSArray<AVMetadataItem *> *)metadataItemsFromArray:(NSArray<AVMetadataItem *> *)metadataItems filteredByMetadataItemFilter:(AVMetadataItemFilter *)metadataItemFilter NS_AVAILABLE(10_9, 7_0);
里面有好幾個(gè)方法進(jìn)行篩選的半夷, 傳進(jìn)一個(gè)篩選前的AVMetadataItem數(shù)組進(jìn)去竿开,根據(jù)identifier, preferredLanguages進(jìn)行篩選玻熙, 這兩個(gè)比較簡(jiǎn)單否彩。
而 根據(jù)key和keySpace的話(huà)就要注意文件的類(lèi)型了
這里的keySpace是根據(jù)文件的類(lèi)型來(lái)的
1、 iTunes: iTunes 包括 Audio/Video 文件格式一般有:.mp4, .m4v, .m4a; 對(duì)應(yīng)的 keySpace 是 AVMetadataKeySpaceiTunes
2嗦随、 Quicktime Metadata 包括 Quicktime movie 格式有: .mov 對(duì)應(yīng)的 keySpace 是 AVMetadataKeySpaceQuickTimeMetadata
3列荔、 Quicktime User Dara 包括 Quicktime movie 格式有: .mov 對(duì)應(yīng)的 keySpace 是 AVMetadataKeySpaceQuickTimeUserData
4、 ID3 包括 MPEG Layer III 格式有:.mp3 對(duì)應(yīng)的 keySpace 是 AVMetadataKeySpaceID3
5枚尼、其中Common類(lèi)型包括了 iTunes, Quicktime Metadata, Quicktime User Dara, ID3等等 是一個(gè)匯總 對(duì)應(yīng)的 keySpace 是AVMetadataKeySpaceCommon
根據(jù)相對(duì)應(yīng)進(jìn)去點(diǎn)進(jìn)去 keySpace 底下就是 key贴浙, 根據(jù)key獲取作者,標(biāo)題署恍,子標(biāo)題崎溃, 創(chuàng)建時(shí)間, 時(shí)長(zhǎng)等信息 都在AVMetadataFormat.h 中
所以一般我們用 AVMetadataKeySpaceCommon 和 AVMetadataKeySpaceCommon底下的key能滿(mǎn)足我們的需求了