Android | 音视频方向进阶路线及资源合集

有 Android 开发的小伙伴问有没有系统学习音视频的路线或者资料,今天抽空写一篇文章,整理一条从难到易从浅入深的路线,并配套对应的主流代码库.
音视频从采集到播放都经历了哪些流程呢::
 
 通过上面的图,我们简单的把音视频方向分为主要的两块:
- 媒体部分(蓝色+绿色) 
- 传输部分(红色) 
1.媒体部分
我们这篇文章不再从音视频专业知识开始,而 Android 系统 API 的角度,逐层深入.
1.1 原始版本
我们最开始接触的摄像拍照是通过 Intent 调用系统摄像头:
我们要播放视频最原始的是基于 VideoView 系统控件.
但是系统相机和系统控件 VideoView 的局限性都是可定制型太差,系统相机的图像分辨率,视频码率以及 VideoView 的进度条等.
1.2 初级版本
接下来,Android 开发中我们接触到最上层的两个 API(Android 官方提供了的么:https://github.com/android/media-samples 包含了 MediaRecorder VideoPlayer 等)是:
- MediaRecorder 音频/视频采集 对应上图蓝色部分, 参考 https://github.com/werbhelius/MediaUtils 实现 
- MediaPlayer 音频/视频播放, (VideoView 封装了 MediaPlayer),对应上图绿色部分 参考:https://github.com/crossle/MediaPlayerSurface 实现 
MediaRecorder 示例:
MediaRecorder 示例:
示例代码简单介绍了一下 MediaRecorder 和 MediaRecorder 的 API,参考上面提供的 demo 已经可以实现简单的播放器和音视频录制功能了.上面我们又引出两个接口来:Camera, Surface. 拍照等功能我们都可以使用 Camera 的接口实现,关于 Camera 的 API 可以参考 google 的 demo:https://github.com/googlearchive/android-Camera2BasicSurface我们接下来介绍.
1.3 进阶版本
上面的的 MediaRecorder,MediaPlayer 直接封装了图中的蓝色部分与绿色部分.它们将输入编码复用以及解码解复用输出封装到了一起,可定制性差:1.MediaPlayer 只支持固定的编码和封装,不支持 rtmp 等 2.MediaRecorder 无法支持 mp3,opus, ogg 等编码,无法对采集到音视频做预处理(比如变声,美颜等)
基于上述几个原因,我们再认识几个 API:
- 视频采集 Camera 
- 音频采集 AudioRecorder 
- 视频预处理:SurfaceTexture, Surface, EGL ,GLES10 
- 音视频编码 MediaCodec MediaFormat 
- 音视频封装(复用) MediaMuxer 
- 音视频(解复用) MediaExtractor 
- 音视频解码 MediaCodec 
- 视频预览 SurfaceView, GLSurfaceView, TextureView 
- 音频播放 AudioTrack 
上述 API Android 也为我们提供了示例https://github.com/google/grafika,里面包含的示例相当全面:
- Play video (TextureView). 基于 MediaCodec ,MediaExtractor, TextureView 封装的播放器,可以帮助理解这几个 api. 
- Continuous capture. 基于 Camera,GLES20,SurfaceTexture,SurfaceView,MediaCodec 实现的建议的视频录制器. 
- Double decode. 类似于 Play video 示例,只是解码两路视频渲染到 TextureView. 
- Hardware scaler exerciser. 演示 OpenGL 进行画面缩放 
- Live camera (TextureView). 演示 Camera,SurfaceTexture 以及 TextureView 使用 
- Multi-surface test. 演示三路视频渲染 
- Play video (SurfaceView). 类似于 Play video (TextureView),只是输出从 TextureView 变成了 SurfaceView. 
- Record GL app. 基于 FBO 同时将摄像头采集数据输出到编码器和屏幕,FBO 是实时美颜的关键技术. 
- Record Screen using MediaProjectionManager.基于 MediaProjectionManager 将屏幕内容录制成文件.之前我们的输入都是摄像头,Android5.0 开始提供了 MediaProjectionManager,可以对屏幕内容进行采集. 
- Scheduled swap. 了解一个新伙伴 Choreographer 
- Show + capture camera. 摄像头同时输出到文件和屏幕(与"RecordFBOActivity"输出对象变成了 GLSurfaceView) 
- Simple Canvas in TextureView. 一般的我们把基于 OpenGL 的渲染称为"硬"渲染,基于 Canvas 的称为"软"渲染,这个示例展示了如何通过 Canvas 绘制到 TextureView 
- Simple GL in TextureView. 可以理解为实现了 GLThread 的 TextureView. 
- Texture from Camera. Camera->SurfaceTexture->SurfaceView 
- Color bars. Canvas 绘制示例 
- OpenGL ES Info. 获取 OpenGL 版本等相关信息 
- glTexImage2D speed test. 纹理上传示例,从图片装换为 OpenGL 纹理,又要认识一个新伙伴: glTexImage2D(). 
- glReadPixels speed test. OpenGL 纹转换为图片(RGBA/YUV),再认识一个新伙伴 glReadPixels() 
 
  
 上面的 demo 主要是图形相关的,编解码器观光一下官方文档:https://developer.android.google.cn/reference/android/media/MediaCodec 已经不能再明白了.
此外,想弄明白 MediaCodec,还需要了解一个数据结构 ByteBuffer(移步官方文档了解一下? https://developer.android.google.cn/reference/java/nio/ByteBuffer)
如果学习完这些,那么恭喜你,你已经对音视频相关知识有了一些了解了.接下来你可以试着去接触一下著名的 android-gpuimage,以及了解 OpenGL 相关的 FBO,PBO,Texture 等,可以处理视频编辑,简单实现美颜等滤镜了.推荐一些 OpenGL 相关文章:
- 第一个 OpenGL 程序:https://blog.csdn.net/fuyajun01/article/details/6705393 
- 计算机图形学网络课程:http://netclass.csu.edu.cn/NCourse/hep089/term/CG_Txt_7_001.htm 
- LearnOpenGl-CN:https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/08%20Coordinate%20Systems/ 
- opengl-tutorial:https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/08%20Coordinate%20Systems/ 
- OpenGl Pixel Buffer Object(PBO):http://www.songho.ca/opengl/gl_pbo.html 
- OpenGL 深入探索——缓冲区对象(*BO):https://blog.csdn.net/panda1234lee/article/details/51546131 
- OpenGL 深入探索——像素缓冲区对象 (PBO):https://blog.csdn.net/panda1234lee/article/details/51546502 
- Android 关于美颜/滤镜 利用 PBO 从 OpenGL 录制视频:https://www.jianshu.com/p/3bc4db687546 
- EGL API Notes 
- Learn OpenGL ES:http://www.learnopengles.com/android-lesson-one-getting-started/ 
- OpenGL Transformation:http://www.songho.ca/opengl/gl_transform.html 
- glsl_tutorial:http://zach.in.tu-clausthal.de/teaching/cg_literatur/glsl_tutorial/ 
- GLSL ES(OpenGL ES 着色器语言)_WebGL 笔记 9:http://www.ayqy.net/blog/glsl-es%EF%BC%88opengl-es%E7%9D%80%E8%89%B2%E5%99%A8%E8%AF%AD%E8%A8%80%EF%BC%89_webgl%E7%AC%94%E8%AE%B09/ 
- OpenGL 纹理坐标 和 顶点坐标映射关系 详解:https://blog.csdn.net/xipiaoyouzi/article/details/53584798 
- https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txtOpenGL 中 FrameBuffer 使用:https://blog.csdn.net/wl_soft50/article/details/7916955 
1.4 高级版本
进阶版本中处理的都是 Java 层数据,有时候我们要编码 mp3,opus 等,手机硬件编码器(就是 MediaCodec)不支持,我们需要引入编解码器库(lame,opus),这些库都是 c/cpp 实现,我们要经过 jni 封装,但是 jni 是有消耗的,那么我们可以不可以直接在 c/cpp 层实现采集,编码,播放呢? 当然是 YES,下面我们再来了解一下 jni 层的 API:
- 图像采集: 图像采集可以使用 Java Camera,通过给 Camera Surface,Surface 再给 jni 的 MediaCodec,也可以试试<camera/NdkCameraManager.h> 
- 声音采集: 了解一下<SLES/OpenSLES_Android.h> , <SLES/OpenSLES.h>, opensl 的文档太粗陋,给你一份 Android 官方 demo:https://github.com/android/ndk-samples/tree/master/audio-echo 
- 编解码: 了解一下<media/NdkMediaCodec.h> 
- 封装(复用)器: <media/NdkMediaMuxer.h> 
- 解封装(解复用)器: <media/NdkMediaExtractor.h> 
- 图像渲染: ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include 下的 EGL, GLES, GLES2, GLES3 等 
 
 如果了解到这,那么恭喜你,可以继续学习一些其他库了:
- lamemp3:Android 只支持 mp3 解码,不支持 mp3 编码,幸好有 lame:官网, 使用示例 文章介绍: 带你写一个 Mp 文件解析器-Mp3 文件结构全解析(一),带你写一个 Mp 文件解析器-Mp3 文件结构全解析(二) 
- opus: 实时语音场景的首选是 opus,但是 Android 还是只能解码不能编码,索性移步:官网,文章介绍 Opus 从入门到精通(一):简介,Opus 从入门到精通(二):编解码器使用, Opus 从入门到精通(三)手撸一个 Opus 编码程序,Opus 从入门到精通(四)Opus 解码程序实现,Opus 从入门到精通(五)OggOpus 封装器全解析,学习到这应该不再需要 demo 了,自己动手来一个吧 
- aac: Android 支持了 aac 硬件编解码,但是出于编码效率以及低端手机考虑,了解一下 FAAC 
- x264: Android 默认支持了 h264 的编解码,但也是出于编码效率及低端手机考虑,了解一下 x264 
- ffmpeg: 现在终于可以了解下传说中的 ffmpeg 了,音视频界的万能神器. 
1.5 终极阶段
现在你可以更深入的了解声音的本质,特性,图像的压缩原理等等,去理解时域与频域,去学习https://charlesliuyx.github.io/2018/02/18/%E3%80%90%E7%9B%B4%E8%A7%82%E8%AF%A6%E8%A7%A3%E3%80%91%E8%AE%A9%E4%BD%A0%E6%B0%B8%E8%BF%9C%E5%BF%98%E4%B8%8D%E4%BA%86%E7%9A%84%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2%E8%A7%A3%E6%9E%90/,这个时候可以把高等数学和线性代数翻出来了.
2.传输部分
传输部分我们音视频领域主要用到的应用层协议:
- http 
- rtmp 
- rtc 
2.1 基于 http 的音视频传输
Android 上面的系统播放器 MediaPlayer 默认支持 http 的,可以传入一个远程的 mp4 地址给 MediaPlayer 播放.但是这种只能实现点播,如果要在 http 上实现直播的话,了解一下 HLS 以及 HttpFLV:https://www.jianshu.com/p/32417d8ee5b6
2.2 rtmp
rtmp 是 adobe 的产物,主要用于直播场景,主播一路上行,观众多路下行
- 深入理解 rtmp(一)之开发环境搭建 
- 深入理解 rtmp(二)之 C++脚手架搭建 
- 深入理解 rtmp(三)之手把手实现握手协议 
- 深入理解 rtmp(四)之协议实现分析 
具体资源,文章里都有介绍了
2.3 rtc
rtmp 实现了直播,但要互动直播就需要 rtc 了.现在好多都是基于 webrtc 的二次开发.
- How to get started with WebRTC and iOS without wasting 10 hours of your life:http://ninjanetic.com/how-to-get-started-with-webrtc-and-ios-without-wasting-10-hours-of-your-life/ 
- WebRTC 1.0: Real-time Communication Between Browsers:https://www.w3.org/TR/webrtc/#intro 
- Android 之 WebRTC 介绍:https://www.tuicool.com/articles/VvueErU 
- SDP for the WebRTC:https://tools.ietf.org/id/draft-nandakumar-rtcweb-sdp-01.html 
- WebRTC 1.0: Real-time Communication Between Browsers:http://w3c.github.io/webrtc-pc/ 
3.资源整理
3.1 摄像头及录制相关
- https://github.com/aserbao/AndroidCamera : 自定义 Android 相机(仿抖音),其中功能包括视频人脸识别贴纸,分段录制,回滚删除,倒计时录制,视频裁剪,视频帧处理,获取视频第一帧,关键帧,视频旋转,滤镜添加,水印添加,Gif 合成到视频,文字转视频,图片转视频,音视频合成,音频变声处理,SoundTouch,Fmod 音频处理。 
- https://github.com/CJT2325/CameraView : 仿微信拍照 Android 控件(轻触拍照,长按摄像) 
- https://github.com/wuhaoyu1990/MagicCamera : Real-time Filter Camera&VideoRecorder And ImageEditor With Face Beauty For Android---包含美颜等 40 余种实时滤镜相机,可拍照、录像、图片修改,吸取了 gpuimage 很多滤镜 
- https://github.com/android/camera-samples : 谷歌官方 demo 
3.2 webrtc
- Pion WebRtc(https://github.com/pion/webrtc ):Pure Go implementation of the WebRTC API 
- WebRtc 学而思镜像(https://gitlab.com/webrtc-mirror/webrtc): 
- WebRtc 声网镜像(https://webrtc.agora.io/mirror/) 
- Flutter-p2p-engine(https://gitee.com/cdnbye/flutter-p2p-engine):Flutter 视频/直播 APP 省流量 &加速,基于 webrtc 
- Android-p2p-engine(https://gitee.com/cdnbye/android-p2p-engine):传输能力基于 WebRTC Datachannel,可以与 CDNBye 的 Web 端插件互联互通 
- UnityRenderStreaming(https://github.com/Unity-Technologies/UnityRenderStreaming):Streaming Server for unity 
- WebRTC 的拥塞控制和带看策略(https://mp.weixin.qq.com/s/Ej63-FTe5-2pkxyXoXBUTw): 
- WebRTC 拥塞控制策略(https://www.freehacker.cn/media/webrtc-gcc/) 
- Google's BBR 拥塞控制算法如何对抗 diu 丢包(https://blog.csdn.net/dog250/article/details/52902029) 
- RTP Media Congestion Avoidance Techniques:https://datatracker.ietf.org/wg/rmcat/charter/ 
- medooze/media-server(https://github.com/medooze/media-server):WebRTC Media Server 
- 涂鸦开源 voip:https://gitee.com/tucodec/relay_server 
- Jackarain/avplayer(https://github.com/Jackarain/avplayer):一个基于 FFmpeg、libtorrent 的 P2P 播放器实现 
- EricssonResearch/openwebrtc:A cross-platform WebRTC client framework based on GStreamer http://www.openwebrtc.org 
- webrtc/apprtc: The video chat demo app based on WebRTC. This project is currently on HOLD with minimal maintenance. https://appr.tc 
- AirenSoft/OvenMediaEngine: OvenMediaEngine (OME) is a streaming engine for real-time live broadcasting with ultra-low latency. https://OvenMediaEngine.com/ome 
- runner365/read_book:一点点从基础做起 从音视频协议原文精读翻译做起,欢迎交流指导! 
- WebRTC in the real world: STUN, TURN and signaling:https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/ 
- WebRTC 的 Android 2 Android 实现:https://blog.csdn.net/youmingyu/article/details/53192714 
- webrtc 进阶-信令篇-之四: 如何为 WebRTC 项目选择信令协议 
- pristineio/webrtc-build-scripts: A set of build scripts useful for building WebRTC libraries for Android and iOS. 
- weizhenwei https://www.jianshu.com/u/102fafe8c6b9: Webrtc 源码分析相关博客 
- WebRTC 代码走读(八):代码目录结构:https://blog.csdn.net/wanghorse/article/details/46387997 
- WEBRtc 相关:https://www.wolfcstech.com/archives/ 
3.3 音视频标准/历史相关
- 编解码和视频处理技术介绍:https://wenku.baidu.com/view/0ce01567f5335a8102d220d5.html?from=search 
- 多媒体技术基础第三方 03 章_数字声音编码:https://wenku.baidu.com/view/f098cf7202768e9951e73893.html?mark_pay_doc=2&mark_rec_page=1&mark_rec_position=4&clear_uda_param=1 
- 音视频系统培训资料(内部):https://wenku.baidu.com/view/3fa2be7b1a37f111f0855b95.html?from=search 
- 音视频编解码技术:https://wenku.baidu.com/view/419f8333a7c30c22590102020740be1e650ecce7.html?from=search 
- 音视频专业知识:https://wenku.baidu.com/view/6ea5db1114791711cc7917bb.html?from=search 
- 音视频通信基础知识:https://wenku.baidu.com/view/7d3c247624c52cc58bd63186bceb19e8b8f6ec30.html?from=search 
- 第二章音频的数字化:https://wenku.baidu.com/view/7154440f6c85ec3a87c2c56d.html 
- 音视频技术及发展:https://wenku.baidu.com/view/4d4f13c74028915f804dc27e.html 
3.4 其他
- rainfly123/flvmuxer(https://github.com/rainfly123/flvmuxer):This tool is used to encapsulate H264 and AAC to RTMP 
- ant-media/LibRtmp-Client-for-Android(https://github.com/ant-media/LibRtmp-Client-for-Android):It is probably the smallest(~60KB, fat version ~300KB) rtmp client for android. It calls librtmp functions over JNI interface http://antmedia.io 
- video-dev/hls.js(https://github.com/video-dev/hls.js):JavaScript HLS client using Media Source Extension https://hls-js.netlify.com/demo 
- rao1219/VideoAnalysisTool(https://github.com/rao1219/VideoAnalysisTool):这是一款视频分析处理工具,目前嵌入了 Visual Tracking 功能,手动勾选视频中第一帧的某个物体,程序自动跟踪该物体在整个视频序列中的位置 
- https://github.com/guoguo11/JSpeex-util:java JNI 调用 C 实现.speex 转换为.wav;使用场景:微信高清语音.speex 解码为.wav 
- https://github.com/kaldi-asr/kaldi:This is the official location of the Kaldi project. http://kaldi-asr.org 
- latelee/H264BSAnalyzer:H264(AVC) and H265(HEVC) bit stream Analyzer, VS2010 MFC project(Windows 7 x64). 
- ZhengfengRao/rtp2mp4:recv rtp(h264+aac), save as mp4 file 
- hmgle/h264_to_rtp:Send H264 file by RTP over UDP 
- kn007/silk-v3-decoder:[Skype Silk Codec SDK]Decode silk v3 audio files (like wechat amr, aud files, qq slk files) and convert to other format (like mp3). Batch conversion support. https://kn007.net/topics/decoding-qq-… 
- SimpleLivePublisher.Lite https://github.com/gezhaoyou/SimpleLivePublisherLite : 简介的 Android 平台直播推流 
其他资源持续整理输出中...
版权声明: 本文为 InfoQ 作者【轻口味】的原创文章。
原文链接:【http://xie.infoq.cn/article/d9125d5c427b5fe35d5ada3c2】。文章转载请联系作者。











 
    
评论 (1 条评论)