AVFoundation(2):核心AVAsset

AVFoundation是一个对多媒体操作的库。多媒体一般以文件或者流的形式存在,显而易见,直接对多媒体进行操作并不是一件愉快的事,这需要我们了解很多底层多媒体方面的知识。AVFoundation为我们提供了一个多媒体的载体类:AVAsset,在AVAsset中有着统一并且友好的接口,我们不需要了解太多多媒体的知识(当然还是需要了解一些的),就能对其进行操作。

基本属性

我们将描述视频基本信息的属性称为基本属性。AVAsset的属性从根本上来说是多媒体文件(如视频文件)的属性,我们先来看看多媒体文件中有哪些属性。用十六进制编辑器打开一个视频文件是最完整的查看视频中信息的方法,不过这样并不利于我们的阅读,因为数据太多了。apple提供了一个很好的查看视频信息的工具Atom Inspector,它会将十六进制的数据归类,并提取出其中有用的信息,即有利于查阅信息,也可以很方便的查看视频完整的16进制,了解视频的结构。
用Atom Inspector打开一个视频文件

我们可以看到在moov的目录下有一个mvhd,mvhd也称为movie header,它是整个视频的描述部分,里面包含着视频的基本信息,如时长,创建时间等。这些信息就是视频文件的基本属性,他们对应到AVAsset中有:

首先duration属性是CMTime类型,CMTime是一个结构体

它既包含了value,又包含了timescale,所以duration属性由视频中的duration和timescale共同组成。

一般QuickTime和MPEG-4格式的mvhd中都有duration和timescale字段。不过其他格式可能不存在这2个字段,这时duration的值就需要通过计算才能得出。
如果创建AVURLAsset时传入的AVURLAssetPreferPreciseDurationAndTimingKey值为NO(不传默认为NO),duration会取一个估计值,计算量比较小。反之如果为YES,duration需要返回一个精确值,计算量会比较大,耗时比较长。

preferredRatepreferredVolume属性分别表示视频默认的速度和音量,这两个属性直接从mvhd中取出来即可,一般情况下,他们的都是1。
creationDate属性表示视频的创建时间,对应着mvhd中的created。如果mvhd中没有创建时间,creationDate会返回nil。

AVAssetTrack

在mvhd下面,我们可以看到有3个轨道(track),一般的视频至少有2个轨道,一个播放声音,一个播放画面。AVFoundation中有一个专门的类承载多媒体中的track:AVAssetTrack。
打开Atom Inspector中的track,我们可以看到,track中有一个tkhd(track header),其中包含了track的基本信息:

跟mvhd类似,tkhd中包含了duration,rate,volume,created,除此之外,tkhd中还有一个很重要的字段:track id,这是视频中track的唯一标示符。在AVAsset中,可以通过trackId,获得特定的track

除了通过trackID获得track之外,AVAsset中还提供了其他3中方式获得track

tracks中包含了当前Asset中的所有track,通过遍历我们可以获得想要的track.
-tracksWithMediaType:方法会根据指定的媒体类型返回一个track数组,数组中包含着Asset中所有指定媒体类型的track。如果Asset中没有这个媒体类型的track,返回一个空数组。AVMediaFormat中一共定义了8种媒体类型:

-tracksWithMediaCharacteristic:方法会根据指定的媒体特征返回track数组,数组的特性与-tracksWithMediaType:类似,如果Asset中没有这个媒体特征的track,返回一个空数组。AVMediaFormat中一共定义了15种媒体特征:

元数据

再往下看有一个meta(meta data)和udta(user data),里面都保存着视频的元数据,不过由于这个视频没有元数据,可能是因为国内正版视频不好找的原因,我找了几个其他的视频也没找到元数据。所以暂且使用AV Foundation开发秘籍中的图片。
用Atom Inspector打开《超人总动员》mov格式的视频,可以看到视频的结构:

在udta中我们可以看到版权(@cpy)持有者为Pixar公司,导演(@dir)是Brad Bird,另外在meta->ilst中电影的名字是the Incredibles,年份是2006年,类型是Kids & Family。这些数据都会存放在AVAsset的metadata中

commonMetadata属性中包含着当前视频常见格式类型的元数据
metadata属性中包含当前视频所有格式类型的元数据
availableMetadataFormats属性中包含当前视频所有可用元数据的格式类型
元数据的格式类型在AVMetadataFormat中定义了很多种,常见的有title、creator、subject、publisher等

以上只是部分format,要了解更多,可以在apple文档中查阅

有了metadataFormat,apple提供了通过fromat获取特定格式类型元数据的方法:

章节元数据

Asset中有一种特殊的元数据:章节。它是AVTimedMetadataGroup类型,这种类型表示一个只在特定时间段有效的元数据集合,也就是说章节中所包含的元数据只在当前章节的时间段有效。AVAsset中有3个章节相关的API:

availableChapterLocales属性表示当前Asset中可用的章节Locale(感觉翻译成地域或者区域在这里都很别扭,所以还是用英文)。数组类型,里面包含NSLocale对象
-chapterMetadataGroupsWithTitleLocale:containingItemsWithCommonKeys:方法通过locale和元数据的commonkey筛选出特定的元数据,这些元数据只在当前章节的时间段有效。
-chapterMetadataGroupsBestMatchingPreferredLanguages:方法通过指定一种语言,返回一个章节元数据数组。数组中越匹配指定语言的元数据,位置越靠前。

媒体选择

一个多媒体文件中相同的媒体特征的东西可能会有很多,比如一个视频中可能会有2种字幕。对于类似选择哪个字幕的问题,Asset提供了3个API:

availableMediaCharacteristicsWithMediaSelectionOptions属性表示当前asset中有效的媒体特征选项。数组类型,里面包含着代表相应媒体特征的string.
-mediaSelectionGroupForMediaCharacteristic:方法通过传入一个媒体特征类型,返回可供选择的媒体选项集合。例如传入字幕的媒体特征类型,返回当前Asset的可供选择的字幕选项集合。
preferredMediaSelection属性是AVMediaSelection类型,他的作用是主要是为各个媒体选项集合提供默认选项。
这里的属性都不是直接的基本属性,可能不是那么容易理解。下面举个简单的例子,以便于理解。打印出当前Asset中默认的媒体选项。

懒惰加载

由于多媒体文件一般比较大,获取或计算出Asset中的属性非常耗时,apple对Asset的属性采用了懒惰加载模式。在创建AVAsset的时候,只生成一个实例,并不初始化属性。只有当第一次访问属性时,系统才会根据多媒体中的数据初始化这个属性。
由于不用同时加载所有属性,耗时问题得到了一定缓解。但是属性加载在计算量比较大的时候仍旧可能会阻塞线程。为了解决这个问题,AVFoundation提供了AVAsynchronousKeyValueLoading协议,可以异步加载属性:

-loadValuesAsynchronouslyForKeys:completionHandler:方法用来异步加载属性,通过keys传入要加载的key数组,在handler中做加载完成的操作。
-statusOfValueForKey:error:方法可以获得属性的加载状态,如果是AVKeyValueStatusLoaded状态,表示已经加载完成。
除此之外,Asset也提供了取消加载的API:

当需要的时候我们可以通过这个API终止加载属性。另外在AVAsset释放的时候会暗中取消所有的加载请求。

End

除了已经介绍的API之外,还有一些BOOL值类型的标识属性,这些属性都比较简单,根据名字就能明白其中的意思。这里就不多介绍了。
最近刚开始研究AVFoundation,可能是玩这个的人不多,网上这方面的资料比较少,所以将最近研究的结果写成博客,以供大家参考,如果有什么不对的地方,希望能多多指教

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

1 1 收藏 评论

关于作者:小笨狼

iOS开发者,目前在百度,iOS的QQ群:159974494 个人主页 · 我的文章 · 3 ·      

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部