目录

第1章 音视频基础概念介绍 1

1.1声音的物理性质 1

1.1.1声音是波 1

1.1.2 声波的三要素 2

1.1.3 声音的传播介质 3

1.1.4 回声 3

1.1.5 共鸣 4

1.2数字音频 4

1.3 音频编码 6

1.4 图像的物理现象 8

1.5图像的数值表示 9

1.5.1 RGB表示方式 9

1.5.2 YUV数值表示方式 10

1.5.3 YUV和RGB的转化 11

1.6视频的编码方式 12

1.6.1视频编码介绍 12

1.6.2编码概念介绍 13

1.7 本章小结 15

第2章 移动端环境搭建 15

2.1 iOS如何搭建一个基础项目 16

2.1.1 Hello world 16

2.1.2增加C++支持 22

2.2 Android如何搭建一个基础项目 23

2.2.1 Hello world 23

2.2.2 增加C++支持 27

2.3 交叉编译的原理与实践 29

2.3.1 交叉编译的原理 29

2.3.2 iOS平台交叉编译的实践 31

2.3.3 Android平台交叉编译的实践 37

2.3.4 使用lame进行编码mp3 43

2.4 本章小结 47

第3章 FFmpeg的介绍与使用 47

3.1 FFmpeg的编译与命令行使用 48

3.1.1 FFmpeg的编译 48

3.1.2 ffmpeg命令行工具使用 56

3.2 ffmpeg API的介绍与使用 66

1. 引用头文件 67

2. 注册协议、格式与编解码器 69

3. 打开媒体文件源,并设置超时回调 69

4. 寻找各个流,并且打开对应的解码器 69

5. 初始化解码后数据的结构体 70

6. 读取流内容并且解码 71

7. 处理解码后的裸数据 72

8. 关闭所有资源 74

3.3 ffmpeg源码结构介绍 75

3.3.1 libavformat与libavcodec介绍 75

3.3.2. ffmpeg通用API分析 76

3.3.3 调用FFmpeg解码时用到的函数分析 78

3.3.4 调用FFmpeg编码时用到的函数分析 79

3.3.5 面向对象的C语言设计 80

3.4 本章小结 82

第4章 移动平台下音视频渲染 82

4.1 AudioUnit介绍与实践 82

4.2 Android平台的音频渲染 92

4.2.1 AudioTrack的介绍与使用 93

4.2.2 OpenSL ES的介绍与使用 96

4.3 视频的渲染 99

4.3.1 OpenGL ES介绍 99

4.3.2 OpenGL ES的实践 100

4.3.3 上下文环境搭建 108

4.3.4 OpenGL ES中的纹理 114

第5章 实现一款视频播放器 119

5.1架构设计 120

5.2 解码模块的实现 125

5.3 音频播放模块的实现 128

5.3.1 Android平台的音频渲染 129

5.3.2 iOS平台的音频渲染 130

5.4 画面播放模块的实现 131

5.4.1 Android平台的视频渲染 131

5.4.2 iOS平台的视频渲染 133

5.5 AVSync模块的实现 135

5.5.1 维护解码线程 135

5.5.2 音视频同步 136

5.6 中控系统, 串联起各个模块 138

5.6.1 初始化阶段 138

5.6.2 运行阶段 140

5.6.3 销毁阶段 141

5.7 本章小结 141

第6章 音视频的采集与编码 142

6.1 音频的采集 142

6.1.1 Android平台的音频采集 143

6.1.2 iOS平台的音频采集 146

6.2 视频画面的采集 149

6.2.1 Android平台的视频画面采集 149

6.2.2 iOS平台的视频画面采集 159

6.3 音频的编码 171

6.3.1 libfdk_aac编码AAC 171

6.3.2 Android平台的硬件编码器MediaCodec 173

6.3.2 iOS平台的硬件编码器AudioToolbox 177

6.4 视频画面的编码 182

6.4.1 libx264编码H264 183

6.4.2 Android平台的硬件编码器 MediaCodec 189

6.4.3 iOS平台的硬件编码器 192

6.5 本章小结 202

第7章 实现一款视频录制应用 202

7.1 视频录制的架构设计 203

7.2 音频模块的实现 206

7.2.1 音频队列的实现 206

7.2.2 Android平台的实现 209

7.2.3 iOS平台的实现 213

7.3 音频编码模块的实现 217

7.3.1 改造编码器 218

7.3.2 编码器适配器 219

7.4 画面采集与编码模块的实现 221

7.4.1 视频队列的实现 222

7.4.2 Android平台画面编码后入队 223

7.4.3 iOS平台画面编码后入队 224

7.5 Mux模块 225

7.5.1 初始化 226

7.5.2 封装和输出 229

7.5.3 销毁资源 233

7.6 中控系统,串联起各个模块 234

第8章 音频效果器的介绍与实践 235

8.1数字音频基础 236

8.1.1波形图 236

8.1.2频谱图 237

8.1.3语谱图 239

8.1.4深入理解时域与频域 240

8.2 数字音频处理 243

8.2.1 快速傅里叶变换 243

8.3 基本乐理知识 250

8.3.1乐谱 250

8.3.2音符的音高与十二平均律 253

8.3.3 音符的时值 254

8.3.4 节拍 255

8.3.4 MIDI格式 256

8.4 混音效果器 258

8.4.1 均衡效果器 258

8.4.2 压缩效果器 262

8.4.3 混响效果器 264

8.5 效果器实现 267

8.5.1 Android平台的实现 267

8.5.2 iOS平台的实现 278

第9章 视频效果器的介绍与实践 282

9.1 图像处理的基本原理 282

9.1.1 亮度调节 283

9.1.2 对比度调节 284

9.1.3 饱和度调节 285

9.2 图像处理的进阶 286

9.2.1 图像的卷积过程 286

9.2.2 锐化效果器 287

9.2.3 高斯模糊算法 289

9.2.4 双边滤波算法 290

9.2.5 图层混合介绍 291

9.3 使用FFmpeg内部的视频滤镜 293

9.3.1 FFmpeg 视频滤镜的介绍 294

9.3.2 滤镜图的构建 295

9.3.3 使用与销毁滤镜图 297

9.3.4常用滤镜介绍 298

9.4 使用OpenGL ES实现视频滤镜 301

9.4.1 加水印 301

9.4.2 添加自定义文字 308

9.4.3 美颜效果器 312

9.4.4 动图贴纸效果器 314

9.4.5 主题效果器 319

9.5 本章小结 323

第10章 专业的视频录制应用实践 323

10.1 视频硬件解码器的使用 324

10.1.1 初始化信息准备 324

10.1.2 VideoToolbox解码H264 325

10.1.3 MediaCodec解码H264 330

10.2 音频效果器的集成 337

10.2.1 Android音效处理系统的实现 338

10.2.2 iOS音效处理系统的实现 341

10.3 一套跨平台的视频效果器的设计与实现 343

10.4集成特效处理库到视频录制项目 350

10.4.1 Android平台特效集成 350

10.4.2 iOS平台特效集成 356

10.5 本章小结 361

第11章 一个直播应用的构建 362

11.1 直播场景分析 362

11.2拉流播放器的构建 364

11.2.1 Android平台播放器增加后处理过程 364

11.2.2 iOS平台播放器增加后处理过程 368

11.3 推流器的构建 371

11.4 第三方云服务介绍 376

11.5 礼物系统的实现 378

11.5.1 Cocos2dX项目的运行原理 379

11.5.2 关键API详解 382

11.5.3实现一款动画 385

11.6 聊天系统的实现 388

11.6.1 Android客户端的WebSocket实现 389

11.6.2 iOS客户端的WebSocket实现 390

11.7 本章小结 391

第12章 直播应用中关键处理 392

12.1 直播应用的细节分析 393

12.2.1 推流端细节分析 393

12.2.2 拉流端细节分析 393

12.2 推流端的关键处理 394

12.2.1 自适应码率的实践 394

12.2.2 统计数据来保证后续的应对策略 401

12.3 拉流端的关键处理 403

12.3.1 重试机制的实践 404

12.3.2 首屏时间的保证 406

12.3.3 统计数据来保证后续的应对策略 411

12.4 本章小结 412

第13章 工欲善记其事,必先利其器 412

13.1 Android平台工具详解 413

13.1.1 ADB工具的熟练使用 413

13.1.2 MAT工具检测Java端的内存泄露 418

13.1.3 NDK工具详解 429

13.1.4 Native层的内存泄露检测 431

13.1.5 Breakpad收集线上Crash 438

13.2 iOS使用Instruments诊断你的应用 442

13.2.1 Debug Navigator 442

13.2.2 Time Profiler 444

13.2.3 Allocations 446

13.2.4 Leaks 447

附录A 通过Ne10的交叉编译输入理解ndk-build

附录B 编码器的使用细节

附录C 视频的表示与编码

为什么要写这本书

整个音视频领域的架构以及开发已经演进了很长的时间,从最开始的广电领域,到PC端的音视频领域,再到本书所介绍的移动端的音视频领域。在这几年中,移动端的音视频领域架构的演进也是巨大的。在移动互联网的发展热潮中,我有幸从事了音视频领域的设计与开发,并且是就职于最时尚的手机KTV—唱吧,这家充满人性化的公司,从而使得我开发出来的东西能够服务于几亿用户。对于音视频的移动端应用,不论是开发还是使用,在近两年内都达到了一个高峰,而作为一名工程师,如何高效地开发出一个音视频App,是一件非常困难的事情,特别是对于对音视频概念不太了解的工程师。我从事软件开发已有7年多的时间,接触音视频领域也已经有5年多的时间,在这5年多的开发过程中,每个时间段都会遇到新的挑战,尤其是在最开始涉足音视频领域的时候,真可谓举步维艰,首先对于音视频的基础概念不是特别清楚,再者在工作中边学边做,很难对整个音视频领域有一个全面的了解,并且市面上没有相关成熟的资料从更高的层次来介绍音视频领域在移动端的演进与发展。这几年的设计实战与开发经验,以及带新人入门的众多感触,让我有了写这本书的动力,同时也是这本书的和核心内容。我希望通过本书可以帮助到更多想要在移动端音视频领域上做出自己想法App的工程师,让大家可以顺利地建立起自己的音视频App。我非常希望能为刚入门的同学或者遇到困难的同学提供帮助,希望大家可以享受整个开发的过程、享受自己开发的产品为人们生活带来便利的成就感。另外从整个音视频开发领域来讲,我也十分希望能够通过本书贡献出自己的绵薄之力。

读者对象

  • 产品经理,这部分读者可以从中了解到音视频在移动端开发实践过程中遇到的很多问题以及对应的优化策略, 例如:如何通过音视频的统计数据为产品提供更加流畅的策略(视频观看的秒开、直播推流的流畅度、视频上传的成功率等)。
  • 项目经理,这部分读者可以从中了解到很多时下流行的名词与概念,不再会因为几个专业名词就让自己不知所措,并且可以有助于更好地评估音视频项目开发中的风险与进度。
  • 测试人员,这部分读者可以从中了解到音视频App中由于处理过程不同而导致的瓶颈问题,当然书中也提到了一些自动化测试相关的命令以及工具,可以对CPU的Load情况、内存的占用情况、内存泄漏问题等进行分析。
  • 架构师与工程师,这部分读者只需要一点移动开发经验就可以阅读本书了;当然如果你已经是一个Senior的移动开发工程师或者架构师的话,那么你读起本书来将更加游刃有余;再进一步,如果你已经是移动领域的音视频开发工程师了,那么恭喜你,我们之间将会有一场关于技术领域内部的对话。
  • 开设相关课程的大学院校。

如何阅读本书

为了避免说教式的讲解给读者带来枯燥乏味的阅读体验,本书会有大量的实例及生产环境下的案例。本书将分为四大部分,第一部分是入门篇,从理论基础开始讲解,最终会产生两个实践项目;第二部分是提高篇,会基于第一部分的项目添加特效,形成一个完整的多媒体项目;第三部分是提高篇,会结合当下比较流行的直播场景进行实际案例分析;第四部分是工具篇,其中介绍了当下大部分可以提高开发以及测试人员效率的工具。下面是各个章节的基本介绍。

第1章,对音视频的基础概念进行介绍,其中包括音视频的基础数据格式,编码后的数据格式以及不同格式之间的相互转换等。

第2章,从零开始讲解如何搭建一个iOS项目和Android项目,并且添加C++支持,因为音视频领域的开发毕竟有相当一部分的代码需要用C++来书写,这样就可以做到两个平台(Android和iOS平台)共用一套代码仓库,以提升开发效率。然后是讲解交叉编译,因为在音视频开发过程中会用到很多第三方开源库,如果将这些库编译到我们的项目中,势必就要进行交叉编译,因此本章会重点讲解这些内容。

第3章,将探讨ffmpeg开源库,对于音视频开发来讲,ffmpeg开源库是众所周知也是普遍使用的,本章首先从编译开始,接着是命令行使用,再到源码结构介绍,以及最后的API调用,以层层递进的方式对ffmpeg开源库展开探讨。

第4章,将讲解如何利用各自平台的API进行声音与画面的渲染以及解码,对于画面的渲染,推荐使用OpenGL ES,并且两个平台可以使用同一个代码仓库。

第5章,有了前四章的基础,我们已经完全可以构建起一个视频播放器了,本书最大的特点就是经过几章基础知识的学习就能立即开始一个项目的实践,通过本章的视频播放器项目,我们将会熟悉播放器是如何工作的。

第6章,本章会重点介绍音视频的采集与编码器。特别是硬件编解码器在各个平台上的使用,使得我们的应用能够更高效(耗电更少、发热更少、界面更流畅)地运行在用户的手机之上。

第7章,有了之前的基础,本章可以继续开发一个视频录制的新项目,该项目可以使得我们更加熟悉音视频应用在各个平台下的实现。

第8章,将讲解如何处理音频流,毕竟让别人听采集出来的干声是很不礼貌的,本章将利用各种特效来美化采集的声音。

第9章,将讲解如何处理视频流,使视频中的颜值变得更高,毕竟爱美之心人皆有之,本章将介绍如何对视频实现美颜滤镜。

第10章,将在第7章的项目基础之上,增加第8章的音频特效,第9章的视频特效,从而构建一个实际生产过程中的多媒体应用。

第11章,继续以项目作为驱动,详细讲解如何基于之前学习的内容构建一个直播的应用,本章将重点介绍推流以及拉流端,同时还会涉及礼物特效、聊天以及第三方云服务的内容介绍。

第12章,由于一个直播应用是很难在一章的篇幅中讲解完毕的,所以本书会将一些核心的处理放在本章中逐个进行讲解。

第13章,将介绍我和我的同事们经常用到的工具和排错方法,与大家分享在日常开发中如何才能更有效率地解决问题,本章并不仅限于音视频的开发领域。

附录里面会有本书的代码以及很多工具的参考内容。

勘误和支持

由于作者的水平有限,编写的时间也很仓促,书中难免会出现一些错误或者不准确的地方,不妥之处在所难免,恳请读者批评指正。为此,我特意创建了一个在线支持与应急方案的二级站点http://music-video.cn。你可以将书中的错误,发布在Bug勘误表页面中,同时如果你遇到任何问题,也可以访问Q&A页面,我将尽量在线上为你提供最满意的解答。书中的全部源文件都将发布在这个网站上,我也会将相应的功能更新及时更正出来。如果你有更多的宝贵意见,也欢迎你发送邮件至我的邮箱zhanxiaokai2008@126.com,我很期待能够听到你们的真挚反馈。

致谢

感谢唱吧与唱吧的每一位同事,是这个公司让我的职业生涯发展到了今天,也是这个公司让我能在音视频领域达到今天的成就,可以说没有唱吧就不会有这本书的问世。

感谢唱吧里的每一位用户,感谢你们对唱吧的长期支持和贡献,没有你们就不会有唱吧的今天,也就不会有这本书的问世。

感谢我的老婆,感谢你对我工作以及写作的支持,是你在我背后默默做了很多事情,才让我把更多的时间和经历放到工作以及写作中。

感谢机械工业出版社华章公司的编辑Lisa老师,感谢你的魄力和远见,在这一年多的时间中始终支持我的写作,正是你的鼓励和帮助引导了我顺利完成全部书稿。

感谢互联网,我从不怀疑我们在互联网上迈出的任何一步都是人类历史向前迈进的一步,感谢众多互联网人的辛苦工作,为我们创造了这么多机遇。

谨以此书,献给我最亲爱的家人、同事,以及众多互联网从业者们。

展晓凯

中国,北京,2017年9月