直播
综述
音视频直播开发中用到的框架:
- 采集音视频数据:AVFoundation
- 视频帧处理:
- GPUImage:基于 OpenGL ES/Metal 封装的高级框架,可作为小团队、没有专门视觉同学的团队的选择。
- OpenGL ES:跨平台使得成为目前绝大多数商用项目的首选
- Metal
- 视频编码
- VideoToolBox(利用 GPU 编码,又称硬件编码,首选)
- FFmpeg(大量选项、指令,可作为进阶选择)
- 音频编码
- AudioToolBox
- FFmpeg
网络层:ST/Socket 负责传输
协议层:RTMP/HLS 负责网络打包
封装层:FLV/TS 负责编解码数据的封装
不同的码流(360P、720P、1080P 等)如何无缝切换:主流的方案是两个播放器,切换时,旧播放器保持播放,新播放器缓冲并解码完成后,在旧播放器即将播放下一个 I 帧时,切换的新播放器对应位置的 I 帧上,实现无缝连接。
FFmpeg
The FFmpeg project tries to provide the best technically possible solution for developers of applications and end users alike. 为终端用户和开发人员,提供相同程度的,最佳的技术方案。(也就是说,这个项目既有提供给开发者的 API 框架,也有提供给用户的终端工具)
FFmpeg Tools (for end users):
- ffmpeg: 格式转换
- ffplay: 媒体播放
- ffprobe: 流媒体分析器
FFmpeg Libraries for developers:
- libavutil 工具类
- libavcodec 编解码
- libavformat 格式转换
- libavdevice 输入/输出设备
- libavfilter 滤镜
- libswscale 图像处理
- libswresample 音频处理
使用 Metal 渲染视频并播放
平时我们用到的播放框架:
- AVPlayer
- ijkplayer, Video player based on ffplay.(跨平台,iOS 使用 Video Toolbox 硬件解码,渲染使用 Open GL ES。)
- kxmovie, A movie player for iOS based on FFmpeg.
使用 GPU 能力的接口会提到“硬件加速”,这部分工作是由 GPU 而不是 CPU 完成的,比如 AVFoundation 中的人脸识别、编解码中的“硬解码”。
Video Toolbox, Work directly with hardware-accelerated video encoding and decoding capabilities.
凡是涉及到美颜、滤镜等功能,均要用到 OpenGL ES/Metal。Shading Language 是视觉团队写的,我们做的更多是对接的工作,需要了解原理。
GPUImage 提供了 OpenGL ES 和 Metal 的封装,让 iOS 开发者更方便地使用。
FFPlay 同步策略
视频文件 mp4 = 图像文件 h264 + 音频文件 aac(目前最主流的格式)。
图像经过解码、渲染、并显示,音频经过解压,播放,那么它们之间如何同步呢?
有三种方法:音频时钟作为主时钟;视频时钟作为主时钟;外部时钟作为主时钟。
// https://github.com/FFmpeg/FFmpeg/blob/master/fftools/ffplay.c
enum {
AV_SYNC_AUDIO_MASTER, /* default choice */
AV_SYNC_VIDEO_MASTER,
AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
};
音视频同步的模式,业界普遍使用的(ffplay 的默认策略):音频时钟作为主时钟。主要原因是人眼对帧率不敏感。如果视频超前,则暂停以等待音频;如果视频落后,则丢弃掉一些帧追赶音频(丢弃 P 帧或 B 帧,不能丢弃 I 帧)。人眼很难察觉。
M3U8
下载一个 m3u8 视频打开后,里面会有 index.m3u8
文件,文件内容可以比对官方文档:Video on Demand playlist construction
EXT-X-PLAYLIST-TYPE
中 EVENT
代表直播,VOD
代表点播。