1.数字媒体
我们是否想过这些媒体内容最初是如何被数字化的呢?我们显然已经处在一个数字化的时代,但是我们还是更习惯模拟信息的世界。我们看到 的信号标志和所听到的音乐都是通过模拟信号传递给我们的,我们的眼睛和耳朵的构造将这 些信息转换为我们大脑能够解析出的电信号。现实生活中的信号是连续的,信号的频率和强 度是在不断变化的;但是数字世界的信号是离散的,由1和0两个状态表示。要将模拟信号转 换成我们能够存储并传输的数字信号,要经过模拟-数字转换过程,我们将这个过程称为采样 (Sampling)。
1.1数字媒体采样
对媒体内容进行数字化主要有两种方式。第一种称为时间采样,这种方法捕捉一个信号 周期内的变化。比如当你在iPhone上记录一个音频备忘录时,在录制期间你所有的音高变化 和声调变化都会被捕捉下来。第二种采样方式是空间采样,一般用在图片数字化和其他可视 化媒体内容数字化的过程中。空间采样包含对一幅图片在一定分辨率之下捕捉其亮度和色度, 进而创建由该图片的像素点数据所构成的数字化结果。当对一段视频进行数字化时,这两种 方式都可以使用,因为通常的视频信号既有空间属性又有时间属性。 幸运的是,开发者不需要对这两个采样过程中所用到的具体数字化信号处理原理有很深 的研究,因为设备硬件可以帮助我们完成模拟信号到数字信号的转换。但是如果不了解这些 采样过程的基本原理及之后数字媒体内容的存储格式的话,在你进一步深入学习AV Foundation更高级、更有趣功能的时候会感到比较吃力。所以我们还需要了解采样过程的相 关知识,下面以音频采样为例逐步对其进行研究。
1.2音频采样介绍
- 人类可以接收的音频范围为 20Hz 到 20kHz,
- 音频数字化的过程包含一个编码方法,称为线性脉冲编码调制(linear pulse-code modulation),比较常见的说法是Linear PCM或LPCM。这个过程采样或测量一个固定的音频 信号,过程的周期率被称为采样率。
- Harry Nyquist是贝尔实验室的一名工程师,他精确地捕捉到了一个特定频率,该频率为 需要采样对象的最高频率的两倍。比如一个你需要捕捉的音频素材的最高频率为10kHz,你 所需要的采样率最起码为20kHz才能得到较好的数字化效果。使用CD录制的音频采样率为 44.1kHz,这就意味着能捕捉到的最大频率为22.05kHz,刚刚高过人耳能够识别的频率范围 (20kHz)。44.1kHz的采样率可能还不能捕捉到初始资源中的所有频率范围,这意味着采样点 可能会受到录制环境的干扰,因为其无法捕捉到Abbey Road会话的细微差别,不过对于人耳 的听觉来说,这已经足够好了。
- 除采样率外,数字音频采样的另一个重要方面是我们能够捕捉到什么精度的音频样本。 振幅在线性坐标系中进行测量,所以会有Linear PCM这个术语。用于保存样本值的字节数定 义了在线性维度上可行的离散度,同时这个信息也被称为音频的位元深度。为每个样本的整 体量化分配过少的位结果信息会导致数字音频信号产生噪声和扭曲。使用位元深度为8的方法 可以提供256个离散级别的数据,对于一些音频资源来说,这个级别的采样率已经足够了,但 对于大部分音频内容来说还不够高。CD音质的位元深度为16,可以达到65 536个离散级别。 专业级别的音频录制环境的位元深度可以达到24或更高。 对信号进行数字化时,如果能够保留原始、未压缩的数字呈现效果,就是该媒体资源最 纯粹的数字形式,但这样做需要大量的存储空间。比如一个44.1kHz、16位LPCM的音频文件 每分钟可能要占用10MB的空间。要数字化一个含12首歌的唱片,每首歌曲时间大概为5分钟 的话,共需要近600MB的存储空间。即使在当今的海量存储和高带宽的情况下,这个文件体 积仍然很大。
- 视频文件由一系列称为“帧”的图片组成,在视频文件的时间轴线上每一帧都表示一个 场景。要创建连续的运动画面,我们需要在短时间间隔内提供特定数量的帧。视频文件一秒 钟内所能展现的帧数称为视频的帧率,并用FPS作为单位进行测量。常见的帧率是24FPS、
25FPS和30FPS。 要知道未压缩的视频内容所需的存储空间,我们首先需要确定每一个独立的帧有多
大。我们知道有许多通用的视频尺寸,但是目前视频资源最流行的宽高比为16:9,意思是 每16个水平像素对应9个垂直像素。在这一宽高比之下最常见的视频尺寸是1280×720和 1920×1080。
2 数字媒体压缩
2.1色彩二次抽样
2.2编解码器压缩
2.3视频编解码器
对于视频编解码而言,AV Foundation提供有限的编解码器集合,只提供苹果公司认定的 目前最主流的几种媒体类型的支持。具体对于视频文件来说,主要可以归结为H.264和Apple ProRes。下面开始学习H.264视频格式标准。2.3.1 H.264
H.264遵循早期的MEPG-1 和MPEG-2标准,但是在以更低比特率得到更高图片质量方面有了长足进步,使其更好地用 于流媒体文件和移动设备及视频摄像头。 H.264与其他形式的MPEG压缩一样,通过以下两个维度缩小了视频文件的尺寸: 空间:压缩独立视频帧,被称为帧内压缩。
时间:通过以组为单位的视频帧压缩冗余数据,这一过程称为帧间压缩。 帧内压缩通过消除包含在每个独立视频帧内的色彩及结构中的冗余信息来进行压缩,因 此可在不降低图片质量的情况下尽可能缩小尺寸。这类压缩同JEPG压缩的原理类似。帧内压 缩也可以作为有损压缩算法,但通常用于对原始图片的一部分进行处理以生成极高质量的照 片。通过这一过程创建的帧称为I-frames。 在帧间压缩中,很多帧被组合在一起作为一组图片(简称GOP),对于GOP所存在的时间 维度的冗余可以被消除。如果想象视频文件中的典型场景,就会有一些特定运动元素的概念, 比如行驶的汽车或街上走路的行人,场景的背景环境通常是固定的。固定的背景环境就代表 一个时间维度上的冗余,这个冗余就可以通过压缩方式进行消除。
- I-frames:这些帧都是一些单独的帧或关键帧,包含创建完整图片需要的所有数据。 每个 GOP 都正好有一个 I-frames。由于它是一个独立帧,其尺寸是最大的,但也是 解压最快的。
- P-frames:P-frames 又称为预测帧,是从基于最近 I-frames 或 P-frames 的可预测的图 片进行编码得到的。P-frames 可以引用最近的预测 P-frames 或一组 I-frames。你将会 经常看到这些被称为“reference frames”的帧,临近的 P-frames 和 B-frames 都可以对 其进行引用。
- B-frames:B-frames 又称为双向帧,是基于使用之前和之后的帧信息进行编码后得到 的帧。几乎不需要存储空间,但其解压过程会耗费较长时间,因为它依赖于周围其他 的帧。
H.264还支持编码视图,用于确定在整个编码过程中所使用的算法。共定义了3个高级标准:
Baseline:这个标准通常用于对移动设备的媒体内容进行处理,提供了最低效的压缩, 因此经过这个标准压缩后的文件仍较大,但是同时这种方法也是最少计算强度的方 法,因为它不支持 B-frames。如果开发者的编译目标是年代比较久远的 iOS 设备,比 如 iPhone 3GS,可能需要用到 Baseline 标准。
Main:这个标准的计算强度要比 Baseline 的高,因为它使用的算法更多,但可以达到 比较高的压缩率。
- High:高标准的方法会得到最高质量的压缩效果,但它也是 3 种方法中计算复杂度最 高的,因为所有能用到的编码技术和算法几乎都用到了。
2.3.2 Apple ProRes
2.4 音频编解码器
只要是Core Audio框架支持的音频编解码,AV Foundation都可以支持,这意味着AV Foundation能够支持大量不同格式的资源。然而在不用线性PCM音频的情况下,更多的只能 使用AAC。2.4.1 AAC
AAC 高级音频编码(AAC)是H.264标准相应的音频处理方式,目前已成为音频流和下载的音频 资源中最主流的编码方式。这种格式比MP3格式有着显著的提升,可以在低比特率的前提下 提供更高质量的音频,是在Web上发布和传播的音频格式中最为理想的。此外,AAC没有来 自证书和许可方面的限制,这一限制曾经在MP3格式上饱受诟病。注意:AV Foundation 和 Core Audio 提供对 MP3 数据解码的支持,但是不支持对其进行编码。
3 容器格式
如果你和大家一样,喜欢在自己的电脑上查找不同类型的媒体文件,你可能会注意到以 各种扩展名结尾的文件,比如.mov、.m4v、.mpg和.m4a等。虽然我们通常将这些类型都认为 是文件格式,但其正确定义应该是这些类型都是文件的容器格式(container format)。
当开发者使用AV Foundation撰写代码时,将遇到两类主要的容器格式,它们分别是:
- QuickTime:QuickTime 是苹果公司在更宏观 QuickTime 架构中定义的最常用格式。 其具有非常高的可靠性并且是一种有着非常清晰定义的格式,被专业领域人士和普通 消费者广泛使用。苹果公司在 QuickTime File Format Specification 文档中对其细节进 行了详细描述,可在Apple Developer Connection网站上找到该文档。我们建议所有 AV Foundation 开发者都应该至少阅读上述文档中基本知识点的介绍章节,因为了解 相关的知识对之后的应用程序开发有帮助。
- MPEG-4:MPEG-4 Part14 规范定义 MPEG-4(MP4)容器格式。这是从 QuickTime 规范 中直接派生出来的一种行业标准格式,所以这两个规范在结构和功能方面非常类似。 MP4 容器格式的官方文件扩展名是.mp4,但有很多不同的变化扩展名也在使用,尤其 是在苹果系统生态环境中。这些变化的文件扩展名仍然使用相同的基本 MP4 容器格 式,它们通常用来区分一些特定的媒体类型,如 m4a 格式的音频文件,还可以使用这 些扩展名来标识一些基本的 MP4 容器,如 m4v 格式的视频文件。
3 播放和录制音频
3.1 理解音频会话
音频会话在应用程序和操作系统之间扮演着中间人的角色。它提供了一种简单实用的方 法使OS得知应用程序应该如何与iOS音频环境进行交互。你不需要了解与音频硬件交互的细 节,只需要对应用程序的行为进行语义上的描述即可。这一点使得你可以指明应用程序的一 般音频行为,并可以把对该行为的管理委托给音频会话,这样OS系统就可以对用户使用音频 的体验进行最适当的管理。 所有iOS应用程序都具有音频会话,无论其是否使用。默认音频会话来自于以下一些预配置:
- 激活了音频播放,但是音频录制未激活。
- 当用户切换响铃/静音开关到“静音”模式时,应用程序播放的所有音频都会消失。
- 当设备显示解锁屏幕时,应用程序的音频处于静音状态。
- 当应用程序播放音频时,所有后台播放的音频都会处于静音状态。 默认音频会话提供了很多实用的功能,但重要的一点是要确保它是应用程序当前正确的 行为。在大部分应用程序中,默认的行为都是好的,但在开发媒体应用程序时一般是不需要
的。幸运的是,通过使用“分类”功能,可以很容易地定制我们的特殊需求。
3.2 音频会话分类
AV Foundation定义了7种分类来描述应用程序所使用的音频行为。
分类 | 作用 | 是否允许混音 | 音频输入 | 音频输出 |
---|---|---|---|---|
Ambient | 游戏、效率应用程序 | ✔ | ✔ | |
Solo Ambient (默认) | 游戏、效率应用程序 | ✔ | ||
Playback | 音频和视频播放器 | 可选 | ✔ | |
Record | 录音机、音频捕捉 | ✔ | ||
Play and Record | VoIP、语音聊天 | 可选 | ✔ | ✔ |
Audio Processing | 离线会话和处理 | |||
Multi-Route | 使用外部硬件的高级 A/V 应用程序 | ✔ | ✔ |
当为应用程序选择合适的分类时,你需要问自己关于这个核心行为的一些问题。比如音 频播放是核心功能还是次要功能?应用程序的音频是否可以和背景声音相混合?应用程序是 否需要捕捉音频输入进行录制或通过网络发送音频?确定了应用程序的核心音频行为后,选 择合适的分类就变得比较容易了。 上述分类所提供的几种常见行为可以满足大部分应用程序的需要,不过如果开发者需要 更复杂的功能,其中一些分类可以通过使用options和modes方法进一步自定义开发。options可以让开发者使用一些附加行为,如使用Playback分类后,应用程序允许将输出音频和背景 声音进行混合。modes可以通过引入被定制的行为进一步对分类进行修改以满足一些特殊需 求。VoIP和视频聊天应用程序常使用这些模式来获得需要的功能,还有一些模式也针对视频 播放和录制应用程序提供了非常有用的功能。
3.3 使用 AVAudioPlayer 播放音频
音频播放是很多应用程序的常见需求,AV Foundation让这一功能的实现变得非常简单, 这一点要归功于一个名为AVAudioPlayer的类。这个类的实例提供了一种简单地从文本或内存 中播放音频的方法。虽然接口很简单,不过它是具有很强功能的组件,并且在Mac和iOS系统 中经常被作为实现音频播放的最佳选择。 AVAudioPlayer构建于Core Audio中的C-based Audio Queue Services的最顶层。所以它可以 提供所有你在Audio Queue Services中所能找到的核心功能,比如播放、循环甚至音频计量, 但使用的是非常简单并友好的Objective-C接口。除非你需要从网络流中播放音频、需要访问 原始音频样本或者需要非常低的时延,否则AVAudioPlayer都能胜任。
3.3.1 对播放进行控制
播放实例包含了所有开发者期望的对播放行为进行控制的方法。调用play方法可以实现 立即播放音频的功能,pause方法可以对播放暂停,那么可想而知stop方法可以停止播放行为。 有趣的是,pause和stop方法在应用程序外面看来实现的功能都是停止当前播放行为。下一时 间里我们调用play方法,通过pause和stop方法停止的音频都会继续播放。这两者最主要的区 别在底层处理上。调用stop方法会撤消调用prepareToPlay时所做的设置,而调用pause方法则 不会。 除了前面描述的标准常规方法之外,开发者还可以使用其他一些有趣的方法,如下所示:
- 修改播放器的音量:播放器的音量独立于系统的音量,我们可以通过对播放器音量的处 理实现很多有趣的效果,比如声音渐隐效果。音量或播放增益定义为 0.0(静音)到 1.0(最 大音量)之间的浮点值。
- 修改播放器的 pan 值,允许使用立体声播放声音:播放器的 pan 值由一个浮点数表示, 范围从-1.0(极左)到 1.0(极右)。默认值为 0.0(居中)。
- 调整播放率:iOS 5 版本中加入了一个强大功能,即允许用户在不改变音调的情况下 调整播放率,范围从 0.5(半速)到 2.0(2 倍速)。如果正记录一首复杂的音乐或语音,放 慢速度会有很大的帮助;当我们想快速浏览一份政府常规会议内容时,加速播放就很 有帮助。
- 通过设置 numberOfLoops 属性实现音频无缝循环:给这个属性设置一个大于 0 的数,可以实现播放器 n 次循环播放。相反,为该属性赋值-1 会导致播放器无 限循环。
3.4 创建 Audio Looper