音视频开源项目
学习方向
- 使用 ImageView, SurfaceView, 自定义View绘制一张图片
- 使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放,并实现读写音频 wav 文件
- 使用 Camera API 进行视频的采集,分别使用 SurfaceView Texture 来预览 Camera 数据, 取到 NV21 的数据回调
- 使用 MediaExtractor 和 MediaMuxer API 解析和封装 mp4 文件
- 学习 OpenGL ES API, 了解 OpenGL 开发的基本流程,使用OpenGL绘制一个三角形
- 学习纹理绘制,能够使用 OpenGL显示一张图片
- 学习 MediaCodec API, 完成音频 AAC 硬编、硬解
- 学习 MediaCodec API, 完成视频 H.264 硬编、硬解
- 串联整个音视频录制流程,完成音视频的采集,编码,封包成 mp4输出
- 串联整个音视频的播放流程,完成 mp4 的解析,音视频的解码、播放和渲染
- 进一步学习 OpenGL,了解如何实现视频的剪裁、旋转、水印、滤镜,并学习 OpenGL 高级特性,如:VBO,VAO,FBO 等等
- 学习 Android 图形图像架构,能够使用 GLSurfaceviw 绘制 Camera 预览画面
- 深入研究音视频相关的网络协议,如 rtmp,hls,以及封包格式,如:flv,mp4
- 深入学习一些音视频领域的开源项目,如 webrtc,ffmpeg,ijkplayer,librtmp 等等
- 将 ffmpeg 库移植到 Android 平台,结合上面积累的经验,编写一款简易的音视频播放器
- 将 x264 库移植到 Android 平台,结合上面积累的经验,完成视频数据 H264 软编功能
- 将 librtmp 库移植到 Android 平台,结合上面积累的经验,完成 Android RTMP 推流功能
- 上面积累的经验,做一款短视频 APP,完成如:断点拍摄、添加水印、本地转码、视频剪辑、视频拼接、MV 特效等功能
音视频学习路线图
基本流程
图片来自 CSDN
- 数据采集
- 数据处理
- 数据编码
- 音视频混合
- 数据传输
YUV-YCbCr
public class Camera {
private static final String TAG = "Camera";
public class Parameters {
// Formats for setPreviewFormat and setPictureFormat.
private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
private static final String PIXEL_FORMAT_YUV420P = "yuv420p";
private static final String PIXEL_FORMAT_RGB565 = "rgb565";
private static final String PIXEL_FORMAT_JPEG = "jpeg";
private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
}
}
采样格式
YUV420SP NV12
音频基础
声波三要素
- 频率:音阶
- 振幅:响度
- 波形:音色
声音是由振动产生的,声音的传播过程也是能量的传播过程
数字音频
- 采样: 奈奎斯特采样定理 AD转换
- 量化: 16 bits的二进制信号的量化范围[-32768,32767]
- 编码: 按照一定的格式记录采样和量化后的数据,比如顺序存储和压缩存储
PCM
PCM: Pulse Code Modulation 脉冲编码调制,音频的原始数据格式,描述PCM数据概念
- 量化格式 sampleFormat 16bits
- 采样率 sampleRate 44100Hz
- 声道数 channel 2
数据比特率 = 44100 x 16 x 2 = 1378.125kbps
一分钟CD音质的原始数据占用的存储空间为 1378.125 x 60 / 8 / 1024 = 10.09MB
音频编码
原始的音频数据较大,需要进行压缩编码才能存储传输,分为有损压缩和无损压缩,不同的压缩算法有不同的压缩比,压缩比越小越容易失真。 压缩编码的原理实际上是压缩掉冗余信号,冗余信号指的是不被人耳感知到的信号,常用的压缩编码格式:
- WAV:只在PCM数据格式前面增加44字节,描述采样率,声道数等信息,音质非常好,适用于多媒体开发中间文件,保存音乐音效素材
- MP3:音质在128kbits以上的,压缩比在10: 1 左右,适合高比特率下对兼容性有要求的音乐欣赏
- AAC:新一代音频有损压缩技术,在小于128kbits码率下表现优异,并且多用于视频中的音频编码
- Ogg: 可以用比MP3更小的码率实现比MP3更好的音质,高低码率下均有良好的表现,兼容性不够好,流媒体特性不支持,适合语音聊天的音频消息场景
图像基础
光的物理现象
光的三原色:红绿蓝 RGB
数字图像原始数据
RGB_565: 16bit模式描述一个像素,R用5个比特表示,G用6个比特表示,B用5个比特标识 RGBA_8888: 32bit模式描述一个像素,1280x720图像大小计算方式 1280 x 720 x 4 = 3.516MB, 这也是位图 Bitmap 在内存中占用的大小
图像压缩
JPEG: ISO制定的静态图像压缩标准,有损压缩
YUV
视频帧的裸数据更多的是使用YUV数据格式,YUV主要应用于优化彩色视频的传输,兼容旧的黑白电视。与RGB视频信号传输相比,最大优点在于降低传输带宽,RGB要求三个独立视频信号同时传输
Y: 明亮度 Luminance 或 Luma 也称灰阶值 U V: 色度 Chrominance Chroma 描述影像的色彩饱和度,指定像素的颜色
对于非压缩的6bit量化的视频来说,一帧1280x720的视频帧,用YUV420P的格式表示,大小为 1280 x 720 x 1 + 1280 x 720 x 0.5 = 1.318MB。 如果fps(一秒的视频帧数目)是24,按照90分钟来计算,那么用YUV420P格式表示的话,数据量大小为 1.318MB x 24fps x 90min x 60s = 166.8GB。
YUV和RGB的转化
凡是渲染到屏幕上的东西必须是RGB格式
视频编码
视频压缩也是通过除去冗余信息进行压缩的,相较于音频数据,视频数据有极强的相关性,包含大量的冗余信息,包括空间上和时间上的
帧间编码技术除区空间上的冗余信息:
- 运动补偿
- 运动表示
- 运动估计
常用视频压缩标准:
- ISO 制定的 Mpeg4 AVC MP4
- ITU-T 制定的 H264
FFmpeg
FFmpep—Fast Forward Move Picture Experts Group
A complete, cross-platform solution to record, convert and stream audio and video.
FFmpeg 是一个音视频领域使用最广泛的开源库。由C语言编写,但广泛的为C/C++、C#、Java、Python等主流编程语言所调用。它集合了几乎所有的编码解码库与流协议,并能任意添加图片或文字水印,几乎能完美处理您对音视频开发领域的几乎所有需求。 FFmpeg的开源协议为LGPL或GPL协议,也就是说它能在一定程度上允许闭源商用,前提是不要使用它的GPL开源的功能。